mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 13:28:41 +00:00
This commit is contained in:
parent
299195811b
commit
8b8be0c28d
38 changed files with 385 additions and 362 deletions
|
|
@ -74,7 +74,7 @@ namespace Cosmos.Kernel.Plugs.Assemblers {
|
|||
SourceValue = 0x8E,
|
||||
Size = 8
|
||||
};
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.EAX, Count = 16 };
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.EAX, SourceValue = 16 };
|
||||
new CPUx86.Move {
|
||||
DestinationRef = new ElementReference("_NATIVE_IDT_Contents"),
|
||||
DestinationIsIndirect = true,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Cosmos.Kernel.Plugs.Assemblers {
|
|||
public override void Assemble(Indy.IL2CPU.Assembler.Assembler aAssembler) {
|
||||
new CPUx86.Call { DestinationLabel = "_CODE_REQUESTED_BREAK_" };
|
||||
new Label("DO_THE_TEST");
|
||||
new CPUx86.Interrupt(0x35);
|
||||
new CPUx86.Interrupt { DestinationValue = 0x35 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@ namespace Cosmos.Kernel.Plugs.Assemblers {
|
|||
new CPUx86.Move { DestinationReg = Registers.EDI, SourceReg = Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0xC }; //address
|
||||
new CPUx86.Move { DestinationReg = Registers.ECX, SourceReg = Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x8 }; //length
|
||||
new CPUx86.Move { DestinationReg = Registers.EAX, SourceValue = 0 };
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.ECX, Count = 1 };
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.ECX, SourceValue = 1 };
|
||||
new CPUx86.JumpIfNotCarry { DestinationLabel = ".step2" };
|
||||
new CPUx86.StoreByteInString();
|
||||
new CPUAll.Label(".step2");
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.ECX, Count = 1 };
|
||||
new CPUx86.ShiftRight { DestinationReg = Registers.ECX, SourceValue= 1 };
|
||||
new CPUx86.JumpIfNotCarry { DestinationLabel = ".step3" };
|
||||
new CPUx86.StoreWordInString();
|
||||
new CPUAll.Label(".step3");
|
||||
new CPUx86.RepeatStosd();
|
||||
new CPUx86.RepeatStos{Size=32};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,33 @@ using Indy.IL2CPU.Assembler.X86;
|
|||
namespace Indy.IL2CPU.Tests.AssemblerTests.X86 {
|
||||
partial class InvalidOpcodeTester {
|
||||
private static void AddExceptions() {
|
||||
opcodesException.Add(typeof(Dec), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false }
|
||||
});
|
||||
opcodesException.Add(typeof(Divide), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false }
|
||||
});
|
||||
opcodesException.Add(typeof(Inc), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false }
|
||||
});
|
||||
opcodesException.Add(typeof(Neg), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false }
|
||||
});
|
||||
opcodesException.Add(typeof(Not), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false }
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments=false }
|
||||
});
|
||||
opcodesException.Add(typeof(Pop), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false,
|
||||
InvalidRegisters=Registers.Get8BitRegisters(), TestMem8=false },
|
||||
InvalidSizes = Instruction.InstructionSizes.Byte
|
||||
});
|
||||
opcodesException.Add(typeof(ShiftLeft), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false},
|
||||
SourceInfo = new Constraints{TestCR=false, TestMem16=false, TestMem32=false, TestMem8=false, InvalidRegisters= from item in Registers.GetRegisters()where item != Registers.CL select item, TestImmediate16=false, TestImmediate32=false}
|
||||
});
|
||||
opcodesException.Add(typeof(ShiftRight), new ConstraintsContainer {
|
||||
DestInfo = new Constraints { TestImmediate16 = false, TestImmediate32 = false, TestImmediate8 = false, TestCR = false, TestSegments = false },
|
||||
SourceInfo = new Constraints{TestCR=false, TestMem16=false, TestMem32=false, TestMem8=false, InvalidRegisters= from item in Registers.GetRegisters()where item != Registers.CL select item, TestImmediate16=false, TestImmediate32=false}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ using Indy.IL2CPU.Assembler.X86;
|
|||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Xml;
|
||||
using Instruction=Indy.IL2CPU.Assembler.X86.Instruction;
|
||||
|
||||
namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
||||
{
|
||||
|
|
@ -19,7 +21,7 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
class ConstraintsContainer {
|
||||
public Constraints SourceInfo;
|
||||
public Constraints DestInfo;
|
||||
public int[] InvalidSizes;
|
||||
public Instruction.InstructionSizes InvalidSizes = Instruction.InstructionSizes.None;
|
||||
}
|
||||
|
||||
public class TestState {
|
||||
|
|
@ -49,6 +51,7 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
public bool TestImmediate32=true;
|
||||
public bool TestRegisters = true;
|
||||
public bool TestCR=true;
|
||||
public bool TestSegments = true;
|
||||
public IEnumerable<Guid> InvalidRegisters;
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +139,8 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
// output results to html
|
||||
var xFile = Path.Combine(Path.GetDirectoryName(typeof(InvalidOpcodeTester).Assembly.Location), "TestResults.html");
|
||||
GenerateHtml(xFile);
|
||||
xFile = Path.Combine(Path.GetDirectoryName(typeof(InvalidOpcodeTester).Assembly.Location), "TestResults.xml");
|
||||
GenerateXml(xFile);
|
||||
Console.WriteLine("Tests finished. Results have been written to '{0}'", xFile);
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
|
@ -145,6 +150,57 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
//
|
||||
}
|
||||
|
||||
private static void GenerateXml(string aFile) {
|
||||
using(var xWriter = XmlWriter.Create(aFile)) {
|
||||
xWriter.WriteStartDocument();
|
||||
xWriter.WriteStartElement("TestResults");
|
||||
{
|
||||
foreach (var xItem in mTestStates) {
|
||||
xWriter.WriteStartElement("TestCase");
|
||||
{
|
||||
xWriter.WriteAttributeString("Instruction", xItem.Instruction);
|
||||
xWriter.WriteAttributeString("Size", xItem.Size.ToString());
|
||||
if (xItem.HasDest) {
|
||||
if (xItem.DestReg == Guid.Empty) {
|
||||
xWriter.WriteAttributeString("DestinationReg", "");
|
||||
} else {
|
||||
xWriter.WriteAttributeString("DestinationReg", Registers.GetRegisterName(xItem.DestReg));
|
||||
}
|
||||
xWriter.WriteAttributeString("DestinationValue", xItem.DestValue.ToString());
|
||||
xWriter.WriteAttributeString("DestinationIsIndirect", xItem.DestIsIndirect.ToString());
|
||||
xWriter.WriteAttributeString("DestinationDisplacement", xItem.DestDisplacement.ToString());
|
||||
} else {
|
||||
xWriter.WriteAttributeString("DestinationReg", "");
|
||||
xWriter.WriteAttributeString("DestinationValue", "");
|
||||
xWriter.WriteAttributeString("DestinationIsIndirect", "");
|
||||
xWriter.WriteAttributeString("DestinationDisplacement", "");
|
||||
}
|
||||
if (xItem.HasSource) {
|
||||
if (xItem.SourceReg == Guid.Empty) {
|
||||
xWriter.WriteAttributeString("SourceReg", "");
|
||||
} else {
|
||||
xWriter.WriteAttributeString("SourceReg", Registers.GetRegisterName(xItem.SourceReg));
|
||||
}
|
||||
xWriter.WriteAttributeString("SourceValue", xItem.SourceValue.ToString());
|
||||
xWriter.WriteAttributeString("SourceIsIndirect", xItem.SourceIsIndirect.ToString());
|
||||
xWriter.WriteAttributeString("SourceDisplacement", xItem.SourceDisplacement.ToString());
|
||||
} else {
|
||||
xWriter.WriteAttributeString("SourceReg", "");
|
||||
xWriter.WriteAttributeString("SourceValue", "");
|
||||
xWriter.WriteAttributeString("SourceIsIndirect", "");
|
||||
xWriter.WriteAttributeString("SourceDisplacement", "");
|
||||
}
|
||||
xWriter.WriteAttributeString("Message", xItem.Message);
|
||||
xWriter.WriteAttributeString("Succeeded", xItem.Success.ToString());
|
||||
}
|
||||
xWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xWriter.WriteEndElement(); //
|
||||
xWriter.WriteEndDocument();
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateHtml(string aFile) {
|
||||
using(var xWriter = new StreamWriter(aFile, false)) {
|
||||
xWriter.WriteLine("<html><body>");
|
||||
|
|
@ -235,6 +291,9 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
}
|
||||
|
||||
private static T CreateInstruction<T>(Type t, byte aSize) {
|
||||
if(t.GetConstructor(new Type[0])==null) {
|
||||
throw new Exception("Type '" + t.FullName + "' doesnt have a parameterless constructor!");
|
||||
}
|
||||
var xResult = (T)Activator.CreateInstance(t);
|
||||
if(aSize!=0) {
|
||||
((IInstructionWithSize)xResult).Size = aSize;
|
||||
|
|
@ -537,10 +596,13 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
continue;
|
||||
if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && (!opcodesException[type].DestInfo.TestCR))))
|
||||
continue;
|
||||
if (Registers.GetRegisters().Contains(register) &&
|
||||
(!opcodesException.ContainsKey(type) ||
|
||||
(opcodesException.ContainsKey(type) && opcodesException[type].DestInfo.InvalidRegisters != null && (!opcodesException[type].DestInfo.InvalidRegisters.Contains(register)))))
|
||||
if ((!opcodesException.ContainsKey(type) ||
|
||||
(opcodesException.ContainsKey(type) && opcodesException[type].DestInfo.InvalidRegisters != null &&
|
||||
(opcodesException[type].DestInfo.InvalidRegisters.Contains(register)))))
|
||||
continue;
|
||||
if(Registers.IsSegment(register) && !(opcodesException.ContainsKey(type) && opcodesException[type].DestInfo.TestSegments)) {
|
||||
continue;
|
||||
}
|
||||
if (size == 0 || Registers.GetSize(register) == size) {
|
||||
xInstruction = CreateInstruction<IInstructionWithDestination>(type, size);
|
||||
aInitInstruction(xInstruction);
|
||||
|
|
@ -841,15 +903,21 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
|
||||
private static void TestInstructionWithDestinationAndSize(Type type)
|
||||
{
|
||||
Console.ForegroundColor=ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 8");
|
||||
TestInstructionWithDestination(type, 8, null);
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 16");
|
||||
TestInstructionWithDestination(type, 16, null);
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 32");
|
||||
TestInstructionWithDestination(type, 32, null);
|
||||
if (!opcodesException.ContainsKey(type) || ((opcodesException[type].InvalidSizes & Instruction.InstructionSizes.Byte) == 0)){
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 8");
|
||||
TestInstructionWithDestination(type, 8, null);
|
||||
}
|
||||
if (!opcodesException.ContainsKey(type) || ((opcodesException[type].InvalidSizes & Instruction.InstructionSizes.Word) == 0)) {
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 16");
|
||||
TestInstructionWithDestination(type, 16, null);
|
||||
}
|
||||
if (!opcodesException.ContainsKey(type) || ((opcodesException[type].InvalidSizes & Instruction.InstructionSizes.DWord) == 0)) {
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("-->Size 32");
|
||||
TestInstructionWithDestination(type, 32, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TestInstructionWithDestinationAndSource(Type type)
|
||||
|
|
@ -862,166 +930,7 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
PropertyInfo source = type.GetProperty("SourceValue");
|
||||
PropertyInfo sindirect = type.GetProperty("SourceIsIndirect");
|
||||
PropertyInfo sreg = type.GetProperty("SourceReg");
|
||||
/*
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
//Test Immediate 8-->reg
|
||||
if (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && opcodesException[type].testImmediate8))
|
||||
{
|
||||
var test = Activator.CreateInstance(type);
|
||||
dest.SetValue(test, (UInt32)30, new object[0]);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
Console.Write("\t --> Immediate 8: ");
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
//Test Immediate 16
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
if (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && opcodesException[type].testImmediate16))
|
||||
{
|
||||
var test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)300, new object[0]);
|
||||
Console.Write("\t --> Immediate 16: ");
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}
|
||||
//Test Immediate 32
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
if (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && opcodesException[type].testImmediate16))
|
||||
{
|
||||
var test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)300000, new object[0]);
|
||||
Console.Write("\t --> Immediate 32: ");
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}
|
||||
//memory 16 bits
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
if (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && opcodesException[type].testMem16))
|
||||
{
|
||||
//no offset
|
||||
Console.WriteLine("\t --> Mem16");
|
||||
Console.Write("\t\t --> no offset: ");
|
||||
var test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)65, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
//offset 16
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("\t\t --> 16bit offset: ");
|
||||
test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)65, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
displacement.SetValue(test, 203, new object[0]);
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
//offset 32
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("\t\t --> 32bit offset");
|
||||
test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)65, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
displacement.SetValue(test, 70000, new object[0]);
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
if (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && opcodesException[type].testMem32))
|
||||
{
|
||||
//no offset
|
||||
Console.WriteLine("\t --> Mem32");
|
||||
Console.Write("\t\t --> no offset: ");
|
||||
var test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)70000, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
//if (Verify())
|
||||
// Console.Write("OK!");
|
||||
//else
|
||||
// Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
//offset 16
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("\t\t --> 16bit offset: ");
|
||||
test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)70000, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
displacement.SetValue(test, (Int16)203, new object[0]);
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
//offset 32
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("\t\t --> 32bit offset");
|
||||
test = Activator.CreateInstance(type);
|
||||
if (size != 0)
|
||||
psize.SetValue(test, size, new object[0]);
|
||||
dest.SetValue(test, (UInt32)70000, new object[0]);
|
||||
dindirect.SetValue(test, true, new object[0]);
|
||||
displacement.SetValue(test, (Int32)70000, new object[0]);
|
||||
if (Verify())
|
||||
Console.Write("OK!");
|
||||
else
|
||||
Console.Write("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}
|
||||
var testReg = Activator.CreateInstance(type);
|
||||
Console.WriteLine("\tRegisters");
|
||||
foreach (Guid register in Registers.getRegisters())
|
||||
{
|
||||
if (!type.Namespace.Contains("SSE") && (Registers.getXMMs().Contains(register)))
|
||||
continue;
|
||||
if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && (!opcodesException[type].testCR))))
|
||||
continue;
|
||||
if (Registers.getRegisters().Contains(register) && (!opcodesException.ContainsKey(type) || (opcodesException.ContainsKey(type) && (!opcodesException[type].invalidDestRegisters.Contains(register)))))
|
||||
continue;
|
||||
if (size != 0)
|
||||
psize.SetValue(testReg, size, new object[0]);
|
||||
dreg.SetValue(testReg, register, new object[0]);
|
||||
Console.Write("\t\t" + Registers.GetRegisterName(register) + ": ");
|
||||
dest.SetValue(testReg, (UInt32)8, new object[0]);
|
||||
if (Verify())
|
||||
Console.WriteLine("Ok!");
|
||||
else
|
||||
Console.WriteLine("Wrong data emitted");
|
||||
Console.WriteLine();
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
private static void TestInstructionWithDestinationAndSourceAndSize(Type type)
|
||||
|
|
@ -1039,7 +948,7 @@ namespace Indy.IL2CPU.Tests.AssemblerTests.X86
|
|||
|
||||
private static void TestSimpleInstruction(Type type)
|
||||
{
|
||||
var test = Activator.CreateInstance(type);
|
||||
var test = CreateInstruction<object>(type, 0);
|
||||
if (Verify())
|
||||
Console.WriteLine("Ok!");
|
||||
else
|
||||
|
|
|
|||
|
|
@ -6,5 +6,10 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("popad")]
|
||||
public class Popad : X86.Instruction {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0x61 }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,11 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("pushad")]
|
||||
public class Pushad: Instruction {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0x60 },
|
||||
DefaultSize=InstructionSize.DWord
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,16 +6,11 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86
|
||||
{
|
||||
[OpCode("cdq")]
|
||||
public class SignExtendAX : Instruction
|
||||
public class SignExtendAX : InstructionWithSize
|
||||
{
|
||||
private int mOldSize;
|
||||
public SignExtendAX(int aOldSize)
|
||||
{
|
||||
mOldSize = aOldSize;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
switch (mOldSize)
|
||||
switch (Size)
|
||||
{
|
||||
case 4:
|
||||
return "cdq";
|
||||
|
|
|
|||
|
|
@ -6,5 +6,27 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("dec")]
|
||||
public class Dec : InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[]{0xFE},
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue=0x8,
|
||||
OperandSizeByte=0,
|
||||
DestinationMemory=true
|
||||
}); //memory
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode=new byte[]{0x48},
|
||||
DestinationReg=Guid.Empty,
|
||||
DestinationRegByte = 0,
|
||||
AllowedSizes=InstructionSizes.DWord | InstructionSizes.Word
|
||||
}); // reg
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xFE },
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0xC8,
|
||||
OperandSizeByte = 0,
|
||||
DestinationReg = Guid.Empty
|
||||
}); // reg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,21 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
/// </summary>
|
||||
[OpCode("div")]
|
||||
public class Divide: InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xF6 },
|
||||
NeedsModRMByte=true,
|
||||
InitialModRMByteValue = 0xF0,
|
||||
OperandSizeByte=0,
|
||||
DestinationReg=Guid.Empty
|
||||
});// register
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] {0xF6},
|
||||
NeedsModRMByte=true,
|
||||
InitialModRMByteValue = 0x30,
|
||||
OperandSizeByte = 0,
|
||||
DestinationMemory=true
|
||||
}); // memory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,26 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("inc")]
|
||||
public class Inc : InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode=new byte[] {0x40},
|
||||
DestinationReg=Guid.Empty,
|
||||
DestinationRegByte=0,
|
||||
AllowedSizes = InstructionSizes.DWord | InstructionSizes.Word
|
||||
}); // reg (alt)
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xFE },
|
||||
DestinationReg = Guid.Empty,
|
||||
NeedsModRMByte=true,
|
||||
InitialModRMByteValue=0xC0,
|
||||
OperandSizeByte=0
|
||||
}); // reg
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xFE },
|
||||
DestinationMemory=true,
|
||||
NeedsModRMByte = true,
|
||||
OperandSizeByte = 0
|
||||
}); // memory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,25 +5,10 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("int")]
|
||||
public class Interrupt : Instruction {
|
||||
public readonly string Number;
|
||||
|
||||
/// <summary>
|
||||
/// Interrupt N4. Indicates integer overflow.
|
||||
/// </summary>
|
||||
public const int INTO = 4;
|
||||
|
||||
public Interrupt(int aNumber)
|
||||
: this(aNumber.ToString()) {
|
||||
}
|
||||
|
||||
public Interrupt(string aNumber) {
|
||||
Number = aNumber;
|
||||
}
|
||||
|
||||
public class Interrupt : InstructionWithDestination {
|
||||
public override string ToString() {
|
||||
//if (Number == INTO) return "into";
|
||||
return "int " + Number;
|
||||
return "int " + DestinationValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,5 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("mul")]
|
||||
public class Multiply: InstructionWithDestinationAndSize {
|
||||
public readonly string Address1;
|
||||
public Multiply(string aAddress1) {
|
||||
Address1 = aAddress1;
|
||||
}
|
||||
public override string ToString() {
|
||||
return "mul " + Address1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,21 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("neg")]
|
||||
public class Neg: InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode=new byte[] {0xF6},
|
||||
NeedsModRMByte=true,
|
||||
InitialModRMByteValue = 0xD8,
|
||||
DestinationReg=Guid.Empty,
|
||||
OperandSizeByte=0
|
||||
}); // register
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[]{0xF6},
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0x18,
|
||||
DestinationMemory = true,
|
||||
OperandSizeByte=0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,13 +11,16 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
OpCode = new byte[] { 0xF6 },
|
||||
DestinationMemory = true,
|
||||
NeedsModRMByte=true,
|
||||
DefaultSize=InstructionSize.DWord,
|
||||
OperandSizeByte=0,
|
||||
InitialModRMByteValue = 0x10
|
||||
}); // memory
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xF6 },
|
||||
DestinationMemory = true,
|
||||
DestinationReg = Guid.Empty,
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0xD0
|
||||
InitialModRMByteValue = 0xD0,
|
||||
OperandSizeByte=0
|
||||
}); // register
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,26 +5,31 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("out")]
|
||||
public class Out: Instruction {
|
||||
public byte Size {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public class Out: InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xE6 },
|
||||
OperandSizeByte=0,
|
||||
DestinationImmediate=true,
|
||||
DestinationImmediateSize=InstructionSize.Byte
|
||||
|
||||
public byte? Port {
|
||||
get;
|
||||
set;
|
||||
}); // fixed port (immediate)
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xEE },
|
||||
OperandSizeByte = 0,
|
||||
DestinationReg=Registers.DX
|
||||
}); // fixed port (register)
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
string xData = "";
|
||||
switch(Size){
|
||||
case 8: xData = "al"; break;
|
||||
case 16: xData = "ax"; break;
|
||||
case 32: xData = "eax"; break;
|
||||
default: throw new Exception("Size " + Size + " not supported in OUT instruction");
|
||||
string xReg = "";
|
||||
switch(Size) {
|
||||
case 8: xReg = "al";break;
|
||||
case 16: xReg = "ax"; break;
|
||||
case 32: xReg = "eax"; break;
|
||||
|
||||
}
|
||||
return "out " + (Port.HasValue ? Port.ToString() : "DX") + ", " + xData;
|
||||
return base.ToString() + ", " + xReg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,27 +3,24 @@ using System.Linq;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("pop")]
|
||||
public class Pop: InstructionWithDestination{
|
||||
public class Pop: InstructionWithDestinationAndSize{
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
AllowedSizes = InstructionSizes.DWord,
|
||||
AllowedSizes = InstructionSizes.DWord | InstructionSizes.Word,
|
||||
OpCode = new byte[] { 0x58 },
|
||||
NeedsModRMByte = false,
|
||||
DestinationReg = Guid.Empty,
|
||||
DefaultSize=InstructionSize.DWord,
|
||||
DestinationRegByte = 0
|
||||
}); // pop to register
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
AllowedSizes = InstructionSizes.DWord,
|
||||
AllowedSizes = InstructionSizes.DWord | InstructionSizes.Word,
|
||||
OpCode = new byte[]{0x8F},
|
||||
NeedsModRMByte=true,
|
||||
DestinationMemory=true,
|
||||
DefaultSize = InstructionSize.DWord
|
||||
}); // pop to memory
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return base.mMnemonic + " dword " + this.GetDestinationAsString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,27 +5,26 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("push")]
|
||||
public class Push : InstructionWithDestination {
|
||||
public class Push : InstructionWithDestinationAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0x50 },
|
||||
AllowedSizes = InstructionSizes.DWord,
|
||||
DestinationReg = Guid.Empty,
|
||||
DestinationRegByte = 0,
|
||||
DestinationRegBitShiftLeft = 0
|
||||
DestinationRegBitShiftLeft = 0,
|
||||
DefaultSize = InstructionSize.DWord
|
||||
}); // register
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0x68 },
|
||||
AllowedSizes = InstructionSizes.DWord,
|
||||
DestinationImmediate = true
|
||||
OpCode = new byte[] { 0x6A },
|
||||
DestinationImmediate = true,
|
||||
DefaultSize = InstructionSize.DWord
|
||||
}); // immediate
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
AllowedSizes = InstructionSizes.DWord,
|
||||
OpCode = new byte[] { 0xFF },
|
||||
NeedsModRMByte = true,
|
||||
DestinationMemory = true,
|
||||
DefaultSize = InstructionSize.DWord,
|
||||
InitialModRMByteValue = 0x30
|
||||
InitialModRMByteValue = 0x30,
|
||||
DefaultSize = InstructionSize.DWord
|
||||
}); // pop to memory
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,10 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
return aRegister == XMM0 || aRegister == XMM1 || aRegister == XMM2 || aRegister == XMM3 || aRegister == XMM4 || aRegister == XMM5 || aRegister == XMM6 || aRegister == XMM7;
|
||||
}
|
||||
|
||||
public static bool IsSegment(Guid aRegister) {
|
||||
return aRegister == CS || aRegister == DS || aRegister == ES || aRegister == FS || aRegister == GS || aRegister == SS;
|
||||
}
|
||||
|
||||
public static bool Is32Bit(Guid aRegister) {
|
||||
return aRegister == EAX || aRegister == EBX || aRegister == ECX || aRegister == EDX || aRegister == ESP || aRegister == EBP || aRegister == ESI || aRegister == EDI || aRegister == CR0 || aRegister == CR1 || aRegister == CR2 || aRegister == CR3 || aRegister == CR4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
public class Registers_Old {
|
||||
public const string EAX = "eax";
|
||||
public const string AX = "ax";
|
||||
public const string AL = "al";
|
||||
public const string AH = "ah";
|
||||
public const string EBX = "ebx";
|
||||
public const string BX = "bx";
|
||||
public const string BL = "bl";
|
||||
public const string BH = "bh";
|
||||
public const string ECX = "ecx";
|
||||
public const string CX = "cx";
|
||||
public const string CL = "cl";
|
||||
public const string CH = "ch";
|
||||
public const string EDX = "edx";
|
||||
public const string DX = "dx";
|
||||
public const string DL = "dl";
|
||||
public const string DH = "dh";
|
||||
public const string AtEAX = "[eax]";
|
||||
public const string AtEBX = "[ebx]";
|
||||
public const string AtECX = "[ecx]";
|
||||
public const string AtEDX = "[edx]";
|
||||
public const string ESP = "esp";
|
||||
public const string AtESP = "[esp]";
|
||||
public const string EBP = "ebp";
|
||||
public const string AtEBP = "[EBP]";
|
||||
public const string EDI = "edi";
|
||||
public const string AtEDI = "[edi]";
|
||||
public const string ESI = "esi";
|
||||
public const string AtESI = "[esi]";
|
||||
public const string CR0 = "CR0";
|
||||
public const string CR1 = "CR1";
|
||||
public const string CR2 = "CR2";
|
||||
public const string CR3 = "CR3";
|
||||
public const string CR4 = "CR4";
|
||||
}
|
||||
}
|
||||
namespace Indy.IL2CPU.Assembler.x86 {
|
||||
public class Registers_Old:X86.Registers_Old{}
|
||||
}
|
||||
29
source/Indy.IL2CPU/Assembler/x86/RepeatStos.cs
Normal file
29
source/Indy.IL2CPU/Assembler/x86/RepeatStos.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("rep stos")]
|
||||
public class RepeatStos: InstructionWithSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xF3, 0xAA },
|
||||
OperandSizeByte=1,
|
||||
DefaultSize=InstructionSize.Word
|
||||
});
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
switch(Size) {
|
||||
case 32:
|
||||
return "rep stosd";
|
||||
case 16:
|
||||
return "rep stosw";
|
||||
case 8:
|
||||
return "rep stosb";
|
||||
default:throw new Exception("Size not supported!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("rep stosb")]
|
||||
public class RepeatStosb : Instruction {
|
||||
//public readonly string Destination;
|
||||
public RepeatStosb() {
|
||||
// Destination = aDestination;
|
||||
}
|
||||
//public override string ToString() {
|
||||
// return "rep stos " + Destinati;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("rep stosd")]
|
||||
public class RepeatStosd: Instruction {
|
||||
//public readonly string Destination;
|
||||
public RepeatStosd() {
|
||||
// Destination = aDestination;
|
||||
}
|
||||
//public override string ToString() {
|
||||
// return "rep stosddword ";
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,10 +4,41 @@ using System.Linq;
|
|||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("shld")]
|
||||
[OpCode("shl")]
|
||||
public class ShiftLeft: InstructionWithDestinationAndSourceAndSize {
|
||||
public override string ToString() {
|
||||
return base.ToString() + ", CL";
|
||||
}
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xD2},
|
||||
NeedsModRMByte=true,
|
||||
InitialModRMByteValue = 0xE0,
|
||||
OperandSizeByte=0,
|
||||
DestinationReg=Guid.Empty,
|
||||
SourceReg=Registers.CL
|
||||
}); // register by CL
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xD2 },
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0x20,
|
||||
OperandSizeByte = 0,
|
||||
DestinationMemory=true,
|
||||
SourceReg = Registers.CL
|
||||
}); // memory by CL
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xC0 },
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0xE0,
|
||||
OperandSizeByte = 0,
|
||||
DestinationReg = Guid.Empty,
|
||||
SourceImmediate=true
|
||||
}); // register by immediate
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xC0 },
|
||||
NeedsModRMByte = true,
|
||||
InitialModRMByteValue = 0x20,
|
||||
OperandSizeByte = 0,
|
||||
DestinationMemory = true,
|
||||
SourceImmediate = true
|
||||
}); // memory by immediate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,18 +5,7 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("shr")]
|
||||
public class ShiftRight: InstructionWithDestination {
|
||||
public byte? Count {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
if (Count.HasValue) {
|
||||
return "shr " + this.GetDestinationAsString() + ", " + Count.Value.ToString();
|
||||
} else {
|
||||
return "shr " + this.GetDestinationAsString() + ", CL";
|
||||
}
|
||||
}
|
||||
public class ShiftRight: InstructionWithDestinationAndSourceAndSize {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ namespace Indy.IL2CPU.Assembler.X86.X {
|
|||
return new PortNumber(aPort);
|
||||
}
|
||||
set {
|
||||
new X86.Out { Port = aPort, Size = 16 };
|
||||
new X86.Out { DestinationValue = aPort, Size = 16 };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
Word = 16,
|
||||
DWord = 32,
|
||||
QWord = 64,
|
||||
All = Byte | Word| DWord
|
||||
}
|
||||
|
||||
public enum InstructionSize {
|
||||
|
|
@ -22,7 +23,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
Byte = 8,
|
||||
Word = 16,
|
||||
DWord = 32,
|
||||
QWord = 64,
|
||||
QWord = 64
|
||||
}
|
||||
public class InstructionData {
|
||||
public class InstructionEncodingOption {
|
||||
|
|
@ -37,7 +38,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
public bool NeedsModRMByte;
|
||||
public byte InitialModRMByteValue;
|
||||
|
||||
public InstructionSizes AllowedSizes;
|
||||
public InstructionSizes AllowedSizes = InstructionSizes.All;
|
||||
public InstructionSize DefaultSize = InstructionSize.DWord;
|
||||
/// <summary>
|
||||
/// the indx in OpCode where the OperandSize bit is encoded
|
||||
|
|
@ -71,6 +72,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
/// is this EncodingOption valid for situations where the Destination is an immediate value
|
||||
/// </summary>
|
||||
public bool DestinationImmediate;
|
||||
public InstructionSize DestinationImmediateSize = InstructionSize.None;
|
||||
|
||||
/// <summary>
|
||||
/// is this EncodingOption valid for situations where the Source is a register?
|
||||
|
|
@ -171,8 +173,12 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
}
|
||||
aEncodingOption = null;
|
||||
for (int i = 0; i < aInstructionData.EncodingOptions.Count; i++) {
|
||||
|
||||
var xEncodingOption = aInstructionData.EncodingOptions[i];
|
||||
if(aInstructionWithSize!=null) {
|
||||
if(((byte)xEncodingOption.AllowedSizes & aInstructionWithSize.Size) != aInstructionWithSize.Size ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (aInstructionWithDestination != null) {
|
||||
if (!(((xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && (aInstructionWithDestination.DestinationReg != Guid.Empty || aInstructionWithDestination.DestinationValue.HasValue)) ||
|
||||
(!(xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && aInstructionWithDestination.DestinationReg == Guid.Empty && aInstructionWithDestination.DestinationValue.HasValue))) {
|
||||
|
|
@ -224,6 +230,19 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((aInstructionWithDestination.DestinationReg != Guid.Empty && !aInstructionWithDestination.DestinationIsIndirect) &&
|
||||
!xEncodingOption.DestinationReg.HasValue) {
|
||||
continue;
|
||||
}
|
||||
//if(!((xEncodingOption.DestinationReg.HasValue && aInstructionWithDestination.DestinationReg != Guid.Empty && (aInstructionWithDestination.DestinationIsIndirect == xEncodingOption.DestinationMemory)) ||
|
||||
// (!(xEncodingOption.DestinationReg.HasValue && (aInstructionWithDestination.DestinationReg == Guid.Empty && (aInstructionWithDestination.DestinationIsIndirect == xEncodingOption.DestinationMemory)))))) {
|
||||
// continue;
|
||||
//}
|
||||
// (!(xEncodingOption.DestinationReg.HasValue && (aInstructionWithDestination.DestinationReg==Guid.Empty) && aInstructionWithDestination.DestinationIsIndirect))
|
||||
// )) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
}
|
||||
if (aInstructionWithSource != null) {
|
||||
if (!(((xEncodingOption.SourceMemory || xEncodingOption.SourceReg.HasValue) && (aInstructionWithSource.SourceReg != Guid.Empty || aInstructionWithSource.SourceValue.HasValue)) ||
|
||||
|
|
@ -253,6 +272,11 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
}
|
||||
|
||||
private static bool DetermineSize(Indy.IL2CPU.Assembler.Assembler aAssembler, out ulong aSize, Instruction aInstruction, IInstructionWithDestination aInstructionWithDestination, IInstructionWithSize aInstructionWithSize, IInstructionWithSource aInstructionWithSource, InstructionData aInstructionData, InstructionData.InstructionEncodingOption aEncodingOption) {
|
||||
if(aInstructionWithSize!=null) {
|
||||
if(aInstructionWithSize.Size == 0) {
|
||||
aInstructionWithSize.Size = (byte)aEncodingOption.DefaultSize;
|
||||
}
|
||||
}
|
||||
aSize = (ulong)aEncodingOption.OpCode.Length;
|
||||
if (aEncodingOption.NeedsModRMByte) {
|
||||
aSize += 1;
|
||||
|
|
@ -308,7 +332,11 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
}
|
||||
if (aInstructionWithDestination != null && aInstructionWithSize != null) {
|
||||
if (aInstructionWithDestination.DestinationValue.HasValue && !aInstructionWithDestination.DestinationIsIndirect) {
|
||||
aSize += (ulong)aInstructionWithSize.Size / 8;
|
||||
var xSize = aInstructionWithSize.Size;
|
||||
if(aEncodingOption.DestinationImmediateSize!=InstructionSize.None) {
|
||||
xSize = (byte)aEncodingOption.DestinationImmediateSize;
|
||||
}
|
||||
aSize += (ulong)xSize / 8;
|
||||
}
|
||||
}
|
||||
if (aInstructionWithDestination != null && aInstructionWithDestination.DestinationRef != null) {
|
||||
|
|
@ -320,7 +348,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
if (aInstructionWithSource != null && aInstructionWithSource.SourceRef != null) {
|
||||
aSize += 4;
|
||||
}
|
||||
if (aInstructionWithDestination != null && (aInstructionWithDestination.DestinationValue.HasValue && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0))) {
|
||||
if (aInstructionWithDestination != null && (aInstructionWithDestination.DestinationValue.HasValue && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0) && aInstructionWithDestination.DestinationIsIndirect)) {
|
||||
aSize += (ulong)aEncodingOption.DefaultSize / 8;
|
||||
}
|
||||
if (aEncodingOption.DefaultSize == InstructionSize.DWord && aInstructionWithSize != null && aInstructionWithSize.Size == 16) {
|
||||
|
|
@ -603,6 +631,9 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
// throw new NotImplementedException("size not known");
|
||||
xInstrSize = (int)aEncodingOption.DefaultSize / 8;
|
||||
}
|
||||
if(aEncodingOption.DestinationImmediateSize != InstructionSize.None) {
|
||||
xInstrSize = ((byte)aEncodingOption.DestinationImmediateSize) / 8;
|
||||
}
|
||||
Array.Copy(BitConverter.GetBytes(xValue), 0, xBuffer, xOffset, xInstrSize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
public abstract class InstructionWithSize: Instruction, IInstructionWithSize {
|
||||
protected InstructionWithSize() {
|
||||
|
||||
}
|
||||
|
||||
public byte Size {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public abstract string ToString();
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.SignExtendAX(4);
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.SignExtendAX { Size = 32 };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
case 8:
|
||||
{
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.SignExtendAX(4);
|
||||
new CPUx86.SignExtendAX { Size = 32 };
|
||||
//all bits of EDX == sign (EAX)
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EBX };
|
||||
//must be equal to EDX
|
||||
new CPUx86.Xor { DestinationReg = CPUx86.Registers.EBX, SourceReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.JumpIfZero { DestinationLabel = NextInstructionLabel };
|
||||
//equals
|
||||
new CPUx86.Interrupt(CPUx86.Interrupt.INTO);
|
||||
new CPUx86.Interrupt{DestinationValue=4};
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
case 2:
|
||||
case 4:
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.SignExtendAX(4);
|
||||
new CPUx86.SignExtendAX { Size = 32 };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Runtime.CompilerServic
|
|||
new Assembler.X86.Push{DestinationReg=Assembler.X86.Registers.EDI, DestinationIsIndirect=true};
|
||||
new Assembler.X86.Add { DestinationReg = Assembler.X86.Registers.EDI, SourceValue = 4 };
|
||||
new Assembler.X86.Move { DestinationReg = Assembler.X86.Registers.EAX, SourceReg = Assembler.X86.Registers.EDI, SourceIsIndirect = true };
|
||||
new Assembler.X86.Multiply("dword [esp]");
|
||||
new Assembler.X86.Multiply{DestinationReg=Assembler.X86.Registers.ESP, DestinationIsIndirect=true, Size=32};
|
||||
new Assembler.X86.Pop { DestinationReg = Assembler.X86.Registers.ECX };
|
||||
new Assembler.X86.Move { DestinationReg = Assembler.X86.Registers.ECX, SourceReg = Assembler.X86.Registers.EAX };
|
||||
new Assembler.X86.Move { DestinationReg = Assembler.X86.Registers.EAX, SourceValue = 0 };
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
|
|||
new CPUx86.Pop { DestinationReg = Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true }; // element size
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EBX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x18 };
|
||||
new CPUx86.Multiply("ebx");
|
||||
new CPUx86.Multiply { DestinationReg = Registers.EBX };
|
||||
new CPUx86.Add { DestinationReg = Registers.EAX, SourceValue = 16 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.ESI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x1C };
|
||||
new CPUx86.Add { DestinationReg = Registers.ESI, SourceReg = Registers.EAX }; // source ptr
|
||||
|
|
@ -30,7 +30,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
|
|||
new CPUx86.Pop { DestinationReg = Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x10 };
|
||||
new CPUx86.Multiply("ecx");
|
||||
new CPUx86.Multiply { DestinationReg = Registers.ECX };
|
||||
new CPUx86.Add{DestinationReg = Registers.EAX, SourceValue=16};
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x14 };
|
||||
new CPUx86.Add{DestinationReg = Registers.EDI, SourceReg=Registers.EAX};
|
||||
|
|
@ -40,7 +40,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers {
|
|||
new CPUx86.Add { DestinationReg = Registers.EAX, SourceValue = 12 };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true};
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0xC };
|
||||
new CPUx86.Multiply("edx");
|
||||
new CPUx86.Multiply { DestinationReg = Registers.EDX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.EAX, };
|
||||
new RepeatMovsb();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public static void Assemble(CPU.Assembler aAssembler, uint aElementSize) {
|
||||
new CPUx86.Pop{DestinationReg=CPUx86.Registers.EAX};
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceValue = aElementSize };
|
||||
new CPUx86.Multiply(CPUx86.Registers_Old.EDX);
|
||||
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = (ObjectImpl.FieldDataOffset + 4) };
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.Registers.EAX };
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
aAssembler.StackContents.Push(new StackContent(4, typeof(uint)));
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceValue = aElementSize };
|
||||
new CPUx86.Multiply(CPUx86.Registers_Old.EDX);
|
||||
new CPUx86.Multiply{DestinationReg=CPUx86.Registers.EDX};
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = (uint)(ObjectImpl.FieldDataOffset + 4) };
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EDX };
|
||||
new CPUx86.Add { DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.Registers.EAX };
|
||||
|
|
|
|||
|
|
@ -152,13 +152,13 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
if (xStackContent.Size > 4) {
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Add { DestinationReg = Registers.ESP, SourceValue = 4 };
|
||||
new CPUx86.Multiply("dword [esp]");
|
||||
new CPUx86.Multiply { DestinationReg = Registers.ESP, DestinationIsIndirect = true, Size = 32 };
|
||||
new CPUx86.Add { DestinationReg = Registers.ESP, SourceValue = 8 };
|
||||
new Push{DestinationValue=0};
|
||||
new Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
} else {
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Multiply("dword [esp]");
|
||||
new CPUx86.Multiply { DestinationReg = Registers.ESP, DestinationIsIndirect = true, Size = 32 };
|
||||
new CPUx86.Add { DestinationReg = Registers.ESP, SourceValue = 4 };
|
||||
new Push { DestinationReg = Registers.EAX };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@
|
|||
<Compile Include="Assembler\x86\JumpToSegment.cs" />
|
||||
<Compile Include="Assembler\x86\MoveIfBelow.cs" />
|
||||
<Compile Include="Assembler\x86\MoveIfLess.cs" />
|
||||
<Compile Include="Assembler\x86\Registers_Old.cs" />
|
||||
<Compile Include="Assembler\x86\X\RegisterEBX.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\Extensions.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\IInstructionWithDestination.cs" />
|
||||
|
|
@ -106,6 +105,7 @@
|
|||
<Compile Include="Assembler\x86\_Infra\InstructionWithDestinationAndSize.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\InstructionWithDestinationAndSource.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\InstructionWithDestinationAndSourceAndSize.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\InstructionWithSize.cs" />
|
||||
<Compile Include="Assembler\_Infra\IDefine.cs" />
|
||||
<Compile Include="Assembler\_Infra\IEndIfDefined.cs" />
|
||||
<Compile Include="Assembler\_Infra\IIfDefined.cs" />
|
||||
|
|
@ -179,8 +179,7 @@
|
|||
<Compile Include="Assembler\x86\Push.cs" />
|
||||
<Compile Include="Assembler\x86\Registers.cs" />
|
||||
<Compile Include="Assembler\x86\RepeatMovsb.cs" />
|
||||
<Compile Include="Assembler\x86\RepeatStosb.cs" />
|
||||
<Compile Include="Assembler\x86\RepeatStosd.cs" />
|
||||
<Compile Include="Assembler\x86\RepeatStos.cs" />
|
||||
<Compile Include="Assembler\x86\Return.cs" />
|
||||
<Compile Include="Assembler\x86\RotateThroughCarryLeft.cs" />
|
||||
<Compile Include="Assembler\x86\RotateThroughCarryRight.cs" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//#define BINARY
|
||||
#define BINARY
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
@ -12,7 +12,7 @@ namespace TestApp {
|
|||
class Program {
|
||||
class Renderer : Y86 {
|
||||
public void DoRender() {
|
||||
new Not { DestinationReg = Registers.CR0, DestinationIsIndirect = true, Size = 8 };
|
||||
new Push {Size=8, DestinationValue = 30 };
|
||||
}
|
||||
}
|
||||
static void Main(string[] args) {
|
||||
|
|
@ -34,7 +34,7 @@ namespace TestApp {
|
|||
"Output"),
|
||||
"TheOutput.bin"), FileMode.Create)) {
|
||||
xAsm.FlushBinary(xOutput, 0x200000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
using (var xOutput = new StreamWriter(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
"Output"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue