Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions source/Cosmos.IL2CPU/IL/Ldelem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

using Cosmos.IL2CPU.ILOpCodes;

namespace Cosmos.IL2CPU.X86.IL
Expand All @@ -17,11 +16,11 @@ public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
var xSize = SizeOfType(xOpType.Value);
if (xOpType.Value.IsValueType && !xOpType.Value.IsPrimitive)
{
Ldelema.Assemble(Assembler, xOpType, xSize, DebugEnabled);
Ldelema.Assemble(Assembler, xOpType, xSize, DebugEnabled, aMethod, aOpCode);
Ldobj.DoAssemble(xOpType.Value);
return;
}
Ldelem_Ref.Assemble(Assembler, xSize, false, aMethod, aOpCode, DebugEnabled);
}
}
}
}
69 changes: 27 additions & 42 deletions source/Cosmos.IL2CPU/IL/Ldelema.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using CPUx86 = XSharp.Assembler.x86;

using Cosmos.IL2CPU.ILOpCodes;
using IL2CPU.API;
Expand All @@ -15,12 +16,36 @@ public Ldelema(XSharp.Assembler.Assembler aAsmblr)
{
}

public static void Assemble(XSharp.Assembler.Assembler aAssembler, OpType aOpType, uint aElementSize, bool debugEnabled)
public static void Assemble(XSharp.Assembler.Assembler aAssembler, OpType aOpType, uint aElementSize, bool debugEnabled, _MethodInfo aMethod, ILOpCode aOpCode)
{
XS.Comment("Arraytype: " + aOpType.StackPopTypes.Last().FullName);
XS.Comment("Size: " + aElementSize);

DoNullReferenceCheck(aAssembler, debugEnabled, 8);

//Do check for index out of range
var xBaseLabel = GetLabel(aMethod, aOpCode);
var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
var xIndexOutOfRangeExeptionLabel = xBaseLabel + "_IndexOutOfRangeException";
XS.Pop(EBX); //get Position _, array, 0, index -> _, array, 0
XS.Push(ESP, true, 4); // _, array, 0 => _, array, 0, array
XS.Push(ESP, true, 12); // _, array, 0, array => _, array, 0, array, 0
Ldlen.Assemble(aAssembler, debugEnabled, false); // _, array, 0, array, 0 -> _, array, 0, length
XS.Pop(EAX); //Length of array _, array, 0, length -> _, array, 0
XS.Compare(EAX, EBX);
XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

XS.Compare(EBX, 0);
XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

XS.Label(xIndexOutOfRangeExeptionLabel);
XS.Pop(EAX);
XS.Pop(EAX);
Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

XS.Label(xNoIndexOutOfRangeExeptionLabel);
XS.Push(EBX); //_, array, 0 -> _, array, 0, index

// calculate element offset into array memory (including header)
XS.Pop(EAX);
XS.Set(EDX, aElementSize);
Expand All @@ -39,47 +64,7 @@ public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
{
var xOpType = (OpType)aOpCode;
var xSize = SizeOfType(xOpType.Value);
Assemble(Assembler, xOpType, xSize, DebugEnabled);
Assemble(Assembler, xOpType, xSize, DebugEnabled, aMethod, aOpCode);
}


// using System;
// using System.IO;
//
//
// using CPU = XSharp.Assembler.x86;
// using CPUx86 = XSharp.Assembler.x86;
// using Cosmos.IL2CPU.X86;
// using Cosmos.IL2CPU.Compiler;
//
// namespace Cosmos.IL2CPU.IL.X86 {
// [XSharp.Assembler.OpCode(OpCodeEnum.Ldelema)]
// public class Ldelema: Op {
// private Type mType;
// public Ldelema(ILReader aReader, MethodInformation aMethodInfo)
// : base(aReader, aMethodInfo) {
// mType= aReader.OperandValueType;
// }
//
// public static void Assemble(CPU.Assembler aAssembler, uint aElementSize) {
// aAssembler.Stack.Pop();
// aAssembler.Stack.Pop();
// aAssembler.Stack.Push(new StackContent(4, typeof(uint)));
// XS.Pop(XSRegisters.EAX);
// XS.Mov(XSRegisters.EDX, aElementSize);
// XS.Multiply(XSRegisters.EDX);
// new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = (uint)(ObjectImpl.FieldDataOffset + 4) };
// XS.Pop(XSRegisters.EDX);
// XS.Add(XSRegisters.EDX, XSRegisters.CPUx86.Registers.EAX);
// XS.Push(XSRegisters.EDX);
// }
//
// public override void DoAssemble() {
// var xElementSize = GetService<IMetaDataInfoService>().SizeOfType(mType);
// Assemble(Assembler, xElementSize);
// }
// }
// }

}
}
77 changes: 61 additions & 16 deletions source/Cosmos.IL2CPU/IL/Stelem_Ref.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using CPUx86 = XSharp.Assembler.x86;
using XSharp.Assembler;
using static XSharp.XSRegisters;


using IL2CPU.API;
using XSharp;
Expand All @@ -27,39 +29,82 @@ public static void Assemble(Assembler aAssembler, uint aElementSize, _MethodInfo
{
xStackSize += 4 - xStackSize % 4;
}
// Do index out of range check
var xBaseLabel = GetLabel(aMethod, aOpCode);
var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
var xIndexOutOfRangeExeptionLabel = xBaseLabel + "_IndexOutOfRangeException";
if (xStackSize == 4)
{
XS.Pop(ECX); //get value _, array, 0, index, value -> _, array, 0, index
}
else if(xStackSize == 8)
{
XS.Pop(ECX); //get value _, array, 0, index, value0, value1 -> _, array, 0, index, value0
XS.Pop(EDX); //get value _, array, 0, index, value0 -> _, array, 0, index
}
else
{
throw new NotImplementedException();
}
XS.Pop(EBX); //get Position _, array, 0, index -> _, array, 0
XS.Push(ESP, true, 4); // _, array, 0 => _, array, 0, array
XS.Push(ESP, true, 12); // _, array, 0, array => _, array, 0, array, 0
Ldlen.Assemble(aAssembler, debugEnabled, false); // _, array, 0, array, 0 -> _, array, 0, length
XS.Pop(EAX); //Length of array _, array, 0, length -> _, array, 0
XS.Compare(EAX, EBX);
XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

XS.Compare(EBX, 0);
XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

XS.Label(xIndexOutOfRangeExeptionLabel);
XS.Pop(EAX);
XS.Pop(EAX);
Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

XS.Label(xNoIndexOutOfRangeExeptionLabel);
XS.Push(EBX); //_, array, 0 -> _, array, 0, index
if (xStackSize == 4)
{
XS.Push(ECX); //_, array, 0 -> _, array, 0, index, value
} else if(xStackSize == 8)
{
XS.Push(EDX); //_, array, 0, index -> _, array, 0, index, value0
XS.Push(ECX); //_, array, 0, index, value0 -> _, array, 0, index, value0, value1
}

// calculate element offset into array memory (including header)
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize); // the index
XS.Set(XSRegisters.EDX, aElementSize);
XS.Multiply(XSRegisters.EDX);
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset + 4);
XS.Set(EAX, ESP, sourceDisplacement: (int)xStackSize); // the index
XS.Set(EDX, aElementSize);
XS.Multiply(EDX);
XS.Add(EAX, ObjectUtils.FieldDataOffset + 4);

XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize + 8); // the array
XS.Add(XSRegisters.EDX, XSRegisters.EAX);
XS.Push(XSRegisters.EDX);
XS.Set(EDX, ESP, sourceDisplacement: (int)xStackSize + 8); // the array
XS.Add(EDX, EAX);
XS.Push(EDX);

XS.Pop(XSRegisters.ECX);
XS.Pop(ECX);
for (int i = (int)(aElementSize / 4) - 1; i >= 0; i -= 1)
{
new Comment(aAssembler, "Start 1 dword");
XS.Pop(XSRegisters.EBX);
XS.Set(XSRegisters.ECX, XSRegisters.EBX, destinationIsIndirect: true);
XS.Add(XSRegisters.ECX, 4);
XS.Pop(EBX);
XS.Set(ECX, EBX, destinationIsIndirect: true);
XS.Add(ECX, 4);
}
switch (aElementSize % 4)
{
case 1:
{
new Comment(aAssembler, "Start 1 byte");
XS.Pop(XSRegisters.EBX);
XS.Set(XSRegisters.ECX, XSRegisters.BL, destinationIsIndirect: true);
XS.Pop(EBX);
XS.Set(ECX, BL, destinationIsIndirect: true);
break;
}
case 2:
{
new Comment(aAssembler, "Start 1 word");
XS.Pop(XSRegisters.EBX);
XS.Set(XSRegisters.ECX, XSRegisters.BX, destinationIsIndirect: true);
XS.Pop(EBX);
XS.Set(ECX, BX, destinationIsIndirect: true);
break;
}
case 0:
Expand All @@ -70,7 +115,7 @@ public static void Assemble(Assembler aAssembler, uint aElementSize, _MethodInfo
throw new Exception("Remainder size " + (aElementSize % 4) + " not supported!");

}
XS.Add(XSRegisters.ESP, 12);
XS.Add(ESP, 12);
}
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
{
Expand Down