This commit is contained in:
mterwoord_cp 2008-11-29 17:26:44 +00:00
parent 299195811b
commit 8b8be0c28d
38 changed files with 385 additions and 362 deletions

View file

@ -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,

View file

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

View file

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

View file

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

View file

@ -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

View file

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

View file

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

View file

@ -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";

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

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

View file

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

View file

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

View file

@ -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
}

View file

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

View file

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

View file

@ -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
}

View file

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

View file

@ -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{}
}

View 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!");
}
}
}
}

View file

@ -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;
//}
}
}

View file

@ -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 ";
//}
}
}

View file

@ -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
}
}
}

View file

@ -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 {
}
}

View file

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

View file

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

View file

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

View file

@ -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;

View file

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

View file

@ -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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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" />

View file

@ -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"),