This commit is contained in:
Matthijs ter Woord 2016-06-16 19:19:14 -04:00
parent 40ff5ad8a7
commit 8a87dfff87
4 changed files with 57 additions and 53 deletions

View file

@ -5,6 +5,7 @@ using CPU = Cosmos.Assembler.x86;
using Cosmos.Assembler; using Cosmos.Assembler;
using Cosmos.IL2CPU.Plugs.System; using Cosmos.IL2CPU.Plugs.System;
using XSharp.Compiler; using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
namespace Cosmos.IL2CPU.X86.IL namespace Cosmos.IL2CPU.X86.IL
{ {
@ -24,18 +25,18 @@ namespace Cosmos.IL2CPU.X86.IL
string xTypeID = GetTypeIDLabel(xType.Value); string xTypeID = GetTypeIDLabel(xType.Value);
XS.Push((ObjectImpl.FieldDataOffset + xSize)); XS.Push((ObjectImpl.FieldDataOffset + xSize));
XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef)); XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef));
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
XS.Set(XSRegisters.ESI, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(ESI, EAX, sourceIsIndirect: true);
XS.Set(XSRegisters.EBX, xTypeID, sourceIsIndirect: true); XS.Set(EBX, xTypeID, sourceIsIndirect: true);
XS.Set(XSRegisters.ESI, XSRegisters.EBX, destinationIsIndirect: true); XS.Set(ESI, EBX, destinationIsIndirect: true);
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESI, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.BoxedValueType, Size = 32 }; XS.Set(ESI, (uint)InstanceTypeEnum.BoxedValueType, destinationDisplacement: 4, size: RegisterSize.Int32);
new Comment(Assembler, "xSize is " + xSize); new Comment(Assembler, "xSize is " + xSize);
for (int i = 0; i < (xSize / 4); i++) for (int i = 0; i < (xSize / 4); i++)
{ {
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EDX));
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESI, DestinationIsIndirect = true, DestinationDisplacement = (ObjectImpl.FieldDataOffset + (i * 4)), SourceReg = CPUx86.RegistersEnum.EDX, Size = 32 }; new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESI, DestinationIsIndirect = true, DestinationDisplacement = (ObjectImpl.FieldDataOffset + (i * 4)), SourceReg = CPUx86.RegistersEnum.EDX, Size = 32 };
} }
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
} }
} }
} }

View file

@ -10,6 +10,7 @@ using System.Reflection;
using Cosmos.IL2CPU.Plugs.System; using Cosmos.IL2CPU.Plugs.System;
using XSharp.Compiler; using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
using SysReflection = System.Reflection; using SysReflection = System.Reflection;
namespace Cosmos.IL2CPU.X86.IL namespace Cosmos.IL2CPU.X86.IL
@ -83,7 +84,7 @@ namespace Cosmos.IL2CPU.X86.IL
{ {
if (xExtraStackSize > 0) if (xExtraStackSize > 0)
{ {
XS.Sub(XSRegisters.OldToNewRegister(CPU.RegistersEnum.ESP), (uint)xExtraStackSize); XS.Sub(OldToNewRegister(CPU.RegistersEnum.ESP), (uint)xExtraStackSize);
} }
XS.Call(xNormalAddress); XS.Call(xNormalAddress);
} }
@ -103,9 +104,9 @@ namespace Cosmos.IL2CPU.X86.IL
} }
else else
{ {
XS.Set(XSRegisters.OldToNewRegister(CPU.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPU.RegistersEnum.ESP), sourceDisplacement: (int)xThisOffset); XS.Set(OldToNewRegister(CPU.RegistersEnum.EAX), OldToNewRegister(CPU.RegistersEnum.ESP), sourceDisplacement: (int)xThisOffset);
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(EAX, EAX, sourceIsIndirect: true);
XS.Push(XSRegisters.EAX, isIndirect: true); XS.Push(EAX, isIndirect: true);
} }
XS.Push(aTargetMethodUID); XS.Push(aTargetMethodUID);
XS.Call(LabelName.Get(VTablesImplRefs.GetMethodAddressForTypeRef)); XS.Call(LabelName.Get(VTablesImplRefs.GetMethodAddressForTypeRef));
@ -126,7 +127,7 @@ namespace Cosmos.IL2CPU.X86.IL
// mLabelName + "_AfterAddressCheck", // mLabelName + "_AfterAddressCheck",
// true, // true,
// xEmitCleanup ); // xEmitCleanup );
XS.Pop(XSRegisters.OldToNewRegister(CPU.RegistersEnum.ECX)); XS.Pop(OldToNewRegister(CPU.RegistersEnum.ECX));
XS.Label(xCurrentMethodLabel + ".AfterAddressCheck"); XS.Label(xCurrentMethodLabel + ".AfterAddressCheck");
if (xMethodInfo.DeclaringType == typeof(object)) if (xMethodInfo.DeclaringType == typeof(object))
@ -138,14 +139,14 @@ namespace Cosmos.IL2CPU.X86.IL
* $esp + mThisOffset This * $esp + mThisOffset This
*/ */
// we need to see if $this is a boxed object, and if so, we need to box it // we need to see if $this is a boxed object, and if so, we need to box it
XS.Set(XSRegisters.OldToNewRegister(CPU.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPU.RegistersEnum.ESP), sourceDisplacement: (int)xThisOffset); XS.Set(OldToNewRegister(CPU.RegistersEnum.EAX), OldToNewRegister(CPU.RegistersEnum.ESP), sourceDisplacement: (int)xThisOffset);
//new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = ( ( uint )InstanceTypeEnum.BoxedValueType ), Size = 32 }; //XS.Compare(XSRegisters.EAX, ( ( uint )InstanceTypeEnum.BoxedValueType ), destinationDisplacement: 4, size: RegisterSizes.Int32);
// EAX contains the handle now, lets dereference it // EAX contains the handle now, lets dereference it
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(EAX, EAX, sourceIsIndirect: true);
new CPU.Compare { DestinationReg = CPU.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (int)InstanceTypeEnum.BoxedValueType, Size = 32 }; XS.Compare(EAX, (int)InstanceTypeEnum.BoxedValueType, destinationDisplacement: 4, size: RegisterSize.Int32);
/* /*
* On the stack now: * On the stack now:
@ -166,8 +167,8 @@ namespace Cosmos.IL2CPU.X86.IL
* EAX contains the type pointer (not the handle!!) * EAX contains the type pointer (not the handle!!)
*/ */
XS.Add(XSRegisters.OldToNewRegister(CPU.RegistersEnum.EAX), (uint)ObjectImpl.FieldDataOffset); XS.Add(OldToNewRegister(CPU.RegistersEnum.EAX), (uint)ObjectImpl.FieldDataOffset);
XS.Set(XSRegisters.ESP, XSRegisters.EAX, destinationDisplacement: (int)xThisOffset); XS.Set(ESP, EAX, destinationDisplacement: (int)xThisOffset);
/* /*
* On the stack now: * On the stack now:
* $esp Params * $esp Params
@ -179,9 +180,9 @@ namespace Cosmos.IL2CPU.X86.IL
XS.Label(xCurrentMethodLabel + ".NotBoxedThis"); XS.Label(xCurrentMethodLabel + ".NotBoxedThis");
if (xExtraStackSize > 0) if (xExtraStackSize > 0)
{ {
XS.Sub(XSRegisters.OldToNewRegister(CPU.RegistersEnum.ESP), xExtraStackSize); XS.Sub(OldToNewRegister(CPU.RegistersEnum.ESP), xExtraStackSize);
} }
XS.Call(XSRegisters.ECX); XS.Call(ECX);
XS.Label(xCurrentMethodLabel + ".AfterNotBoxedThis"); XS.Label(xCurrentMethodLabel + ".AfterNotBoxedThis");
} }
ILOp.EmitExceptionLogic(Assembler, aMethod, aOp, true, ILOp.EmitExceptionLogic(Assembler, aMethod, aOp, true,

View file

@ -1,5 +1,6 @@
using System; using System;
using XSharp.Compiler; using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
using CPUx86 = Cosmos.Assembler.x86; using CPUx86 = Cosmos.Assembler.x86;
namespace Cosmos.IL2CPU.X86.IL namespace Cosmos.IL2CPU.X86.IL
{ {
@ -19,10 +20,10 @@ namespace Cosmos.IL2CPU.X86.IL
Type mType = (( Cosmos.IL2CPU.ILOpCodes.OpType )aOpCode).Value; Type mType = (( Cosmos.IL2CPU.ILOpCodes.OpType )aOpCode).Value;
mObjSize = SizeOfType( mType ); mObjSize = SizeOfType( mType );
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
for( int i = 0; i < ( mObjSize / 4 ); i++ ) for( int i = 0; i < ( mObjSize / 4 ); i++ )
{ {
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = i * 4, SourceValue = 0, Size = 32 }; XS.Set(EAX, 0, destinationDisplacement: i * 4, size: RegisterSize.Int32);
} }
switch( mObjSize % 4 ) switch( mObjSize % 4 )
{ {
@ -90,7 +91,7 @@ namespace Cosmos.IL2CPU.X86.IL
// Assembler.Stack.Pop(); // Assembler.Stack.Pop();
// XS.Pop(XSRegisters.EAX); // XS.Pop(XSRegisters.EAX);
// for (int i = 0; i < (mObjSize / 4); i++) { // for (int i = 0; i < (mObjSize / 4); i++) {
// new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = i * 4, SourceValue = 0, Size=32 }; // XS.Mov(XSRegisters.EAX, 0, destinationDisplacement: i * 4, size: RegisterSizes.Int32);
// } // }
// switch (mObjSize % 4) { // switch (mObjSize % 4) {
// case 1: { // case 1: {

View file

@ -7,6 +7,7 @@ using System.Reflection;
using Cosmos.IL2CPU.Plugs.System; using Cosmos.IL2CPU.Plugs.System;
using XSharp.Compiler; using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
using SysReflection = System.Reflection; using SysReflection = System.Reflection;
namespace Cosmos.IL2CPU.X86.IL namespace Cosmos.IL2CPU.X86.IL
@ -86,15 +87,15 @@ namespace Cosmos.IL2CPU.X86.IL
XS.Comment("Shift: " + xShift); XS.Comment("Shift: " + xShift);
if (xShift < 0) if (xShift < 0)
{ {
XS.Sub(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), (uint)Math.Abs(xShift)); XS.Sub(OldToNewRegister(CPUx86.RegistersEnum.ESP), (uint)Math.Abs(xShift));
} }
else if (xShift > 0) else if (xShift > 0)
{ {
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), (uint)xShift); XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), (uint)xShift);
} }
// push struct ptr // push struct ptr
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.ESP));
// Shift args // Shift args
foreach (var xParam in xParameterList) foreach (var xParam in xParameterList)
@ -131,14 +132,14 @@ namespace Cosmos.IL2CPU.X86.IL
&& xParams[0].ParameterType == typeof(char[])) && xParams[0].ParameterType == typeof(char[]))
{ {
xHasCalcSize = true; xHasCalcSize = true;
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true); XS.Set(EAX, ESP, sourceIsIndirect: true);
// EAX contains a memory handle now, lets dereference it to a pointer // EAX contains a memory handle now, lets dereference it to a pointer
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(EAX, EAX, sourceIsIndirect: true);
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), sourceDisplacement: 8); XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.EAX), sourceDisplacement: 8);
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), 2); XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDX), 2);
XS.Multiply(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX)); XS.Multiply(OldToNewRegister(CPUx86.RegistersEnum.EDX));
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
} }
else if (xParams.Length == 3 else if (xParams.Length == 3
&& (xParams[0].ParameterType == typeof(char[]) || xParams[0].ParameterType == typeof(char*)) && (xParams[0].ParameterType == typeof(char[]) || xParams[0].ParameterType == typeof(char*))
@ -146,18 +147,18 @@ namespace Cosmos.IL2CPU.X86.IL
&& xParams[2].ParameterType == typeof(int)) && xParams[2].ParameterType == typeof(int))
{ {
xHasCalcSize = true; xHasCalcSize = true;
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true); XS.Set(EAX, ESP, sourceIsIndirect: true);
XS.ShiftLeft(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), 1); XS.ShiftLeft(OldToNewRegister(CPUx86.RegistersEnum.EAX), 1);
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
} }
else if (xParams.Length == 2 else if (xParams.Length == 2
&& xParams[0].ParameterType == typeof(char) && xParams[0].ParameterType == typeof(char)
&& xParams[1].ParameterType == typeof(int)) && xParams[1].ParameterType == typeof(int))
{ {
xHasCalcSize = true; xHasCalcSize = true;
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true); XS.Set(EAX, ESP, sourceIsIndirect: true);
XS.ShiftLeft(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), 1); XS.ShiftLeft(OldToNewRegister(CPUx86.RegistersEnum.EAX), 1);
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
} }
else else
{ {
@ -171,15 +172,15 @@ namespace Cosmos.IL2CPU.X86.IL
XS.Push((uint)(xMemSize + xExtraSize)); XS.Push((uint)(xMemSize + xExtraSize));
if (xHasCalcSize) if (xHasCalcSize)
{ {
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
XS.Add(XSRegisters.ESP, XSRegisters.EAX, destinationIsIndirect: true); XS.Add(ESP, EAX, destinationIsIndirect: true);
} }
// todo: probably we want to check for exceptions after calling Alloc // todo: probably we want to check for exceptions after calling Alloc
XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef)); XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef));
XS.Label(".AfterAlloc"); XS.Label(".AfterAlloc");
XS.Push(XSRegisters.ESP, isIndirect: true); XS.Push(ESP, isIndirect: true);
XS.Push(XSRegisters.ESP, isIndirect: true); XS.Push(ESP, isIndirect: true);
// it's on the stack now 3 times. Once from the Alloc return value, twice from the pushes // it's on the stack now 3 times. Once from the Alloc return value, twice from the pushes
@ -196,12 +197,12 @@ namespace Cosmos.IL2CPU.X86.IL
// todo: use a cleaner approach here. this class shouldnt assemble the string // todo: use a cleaner approach here. this class shouldnt assemble the string
string strTypeId = GetTypeIDLabel(constructor.DeclaringType); string strTypeId = GetTypeIDLabel(constructor.DeclaringType);
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(EAX, EAX, sourceIsIndirect: true);
XS.Set(XSRegisters.EBX, strTypeId, sourceIsIndirect: true); XS.Set(EBX, strTypeId, sourceIsIndirect: true);
XS.Set(XSRegisters.EAX, XSRegisters.EBX, destinationIsIndirect: true); XS.Set(EAX, EBX, destinationIsIndirect: true);
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32 }; XS.Set(EAX, (uint)InstanceTypeEnum.NormalObject, destinationDisplacement: 4, size: RegisterSize.Int32);
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32 }; XS.Set(EAX, (uint)xGCFieldCount, destinationDisplacement: 8, size: RegisterSize.Int32);
uint xSize = (uint)(from item in xParams uint xSize = (uint)(from item in xParams
let xQSize = Align(SizeOfType(item.ParameterType), 4) let xQSize = Align(SizeOfType(item.ParameterType), 4)
select (int)xQSize).Take(xParams.Length).Sum(); select (int)xQSize).Take(xParams.Length).Sum();
@ -221,7 +222,7 @@ namespace Cosmos.IL2CPU.X86.IL
if (aMethod != null) if (aMethod != null)
{ {
// todo: only happening for real methods now, not for ctor's ? // todo: only happening for real methods now, not for ctor's ?
XS.Test(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), 2); XS.Test(OldToNewRegister(CPUx86.RegistersEnum.ECX), 2);
string xNoErrorLabel = currentLabel + ".NoError" + LabelName.LabelCount.ToString(); string xNoErrorLabel = currentLabel + ".NoError" + LabelName.LabelCount.ToString();
XS.Jump(CPUx86.ConditionalTestEnum.Equal, xNoErrorLabel); XS.Jump(CPUx86.ConditionalTestEnum.Equal, xNoErrorLabel);
@ -238,7 +239,7 @@ namespace Cosmos.IL2CPU.X86.IL
PushAlignedParameterSize(constructor); PushAlignedParameterSize(constructor);
// an exception occurred, we need to cleanup the stack, and jump to the exit // an exception occurred, we need to cleanup the stack, and jump to the exit
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
//new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]"); //new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]");
//foreach( var xStackInt in Assembler.Stack ) //foreach( var xStackInt in Assembler.Stack )
@ -250,7 +251,7 @@ namespace Cosmos.IL2CPU.X86.IL
Jump_Exception(aMethod); Jump_Exception(aMethod);
XS.Label(xNoErrorLabel); XS.Label(xNoErrorLabel);
} }
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ ) //for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
//{ //{
@ -264,7 +265,7 @@ namespace Cosmos.IL2CPU.X86.IL
//} //}
PushAlignedParameterSize(constructor); PushAlignedParameterSize(constructor);
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
} }
} }
@ -277,7 +278,7 @@ namespace Cosmos.IL2CPU.X86.IL
for (int i = 0; i < xParams.Length; i++) for (int i = 0; i < xParams.Length; i++)
{ {
xSize = SizeOfType(xParams[i].ParameterType); xSize = SizeOfType(xParams[i].ParameterType);
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), Align(xSize, 4)); XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), Align(xSize, 4));
} }
XS.Comment("[ Newobj.PushAlignedParameterSize end ]"); XS.Comment("[ Newobj.PushAlignedParameterSize end ]");
} }