mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 14:02:19 +00:00
commit
cfcf19cc53
4 changed files with 189 additions and 39 deletions
|
|
@ -2,33 +2,71 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Cosmos.TestRunner;
|
||||
|
||||
namespace Cosmos.Compiler.Tests.Bcl.System.Collections.Generic
|
||||
{
|
||||
public static class ListTest
|
||||
{
|
||||
|
||||
public static void Execute()
|
||||
{
|
||||
var xList = new List<int>();
|
||||
|
||||
Assert.AreEqual(0, xList.Count, "Count != 0 at start!");
|
||||
|
||||
xList.Add(0);
|
||||
xList.Add(1);
|
||||
xList.Add(2);
|
||||
|
||||
Assert.AreEqual(3, xList.Count, "After adding 3 items, count != 3");
|
||||
Assert.AreEqual(0, xList[0], "List[0] != 0");
|
||||
Assert.AreEqual(1, xList[1], "List[1] != 1");
|
||||
Assert.AreEqual(2, xList[2], "List[2] != 2");
|
||||
Assert.AreEqual(0, xList[0], "List<int>.Add: xList[0] != 0");
|
||||
Assert.AreEqual(1, xList[1], "List<int>.Add: xList[1] != 1");
|
||||
Assert.AreEqual(2, xList[2], "List<int>.Add: xList[2] != 2");
|
||||
|
||||
var xArray = xList.ToArray();
|
||||
|
||||
Assert.AreEqual(3, xArray.Length, "xArray.Length != 3");
|
||||
Assert.AreEqual(0, xArray[0], "xArray[0] != 0");
|
||||
Assert.AreEqual(1, xArray[1], "xArray[1] != 1");
|
||||
Assert.AreEqual(2, xArray[2], "xArray[2] != 2");
|
||||
Assert.AreEqual(3, xArray.Length, "List<int>.ToArray: xArray.Length != 3");
|
||||
Assert.AreEqual(0, xArray[0], "List<int>.ToArray: xArray[0] != 0");
|
||||
Assert.AreEqual(1, xArray[1], "List<int>.ToArray: xArray[1] != 1");
|
||||
Assert.AreEqual(2, xArray[2], "List<int>.ToArray: xArray[2] != 2");
|
||||
|
||||
xList.Insert(1, 5);
|
||||
|
||||
Assert.AreEqual(0, xList[0], "List<int>.Insert: xList[0] != 0");
|
||||
Assert.AreEqual(5, xList[1], "List<int>.Insert: xList[1] != 5");
|
||||
Assert.AreEqual(1, xList[2], "List<int>.Insert: xList[2] != 1");
|
||||
Assert.AreEqual(2, xList[3], "List<int>.Insert: xList[3] != 2");
|
||||
|
||||
xList.RemoveAt(2);
|
||||
|
||||
Assert.AreEqual(0, xList[0], "List<int>.RemoveAt: xList[0] != 0");
|
||||
Assert.AreEqual(5, xList[1], "List<int>.RemoveAt: xList[1] != 5");
|
||||
Assert.AreEqual(2, xList[2], "List<int>.RemoveAt: xList[2] != 2");
|
||||
|
||||
// Commented tests depend on #583
|
||||
|
||||
//xList.AddRange(new List<int>() { 3, 4, 5 });
|
||||
|
||||
//Assert.AreEqual(0, xList[0], "List<int>.AddRange: xList[0] != 0");
|
||||
//Assert.AreEqual(5, xList[1], "List<int>.AddRange: xList[1] != 5");
|
||||
//Assert.AreEqual(2, xList[2], "List<int>.AddRange: xList[2] != 2");
|
||||
//Assert.AreEqual(3, xList[2], "List<int>.AddRange: xList[3] != 3");
|
||||
//Assert.AreEqual(4, xList[2], "List<int>.AddRange: xList[4] != 4");
|
||||
//Assert.AreEqual(5, xList[2], "List<int>.AddRange: xList[5] != 5");
|
||||
|
||||
//xList.RemoveRange(2, 2);
|
||||
|
||||
//Assert.AreEqual(0, xList[0], "List<int>.RemoveRange: xList[0] != 0");
|
||||
//Assert.AreEqual(5, xList[1], "List<int>.RemoveRange: xList[1] != 5");
|
||||
//Assert.AreEqual(4, xList[2], "List<int>.RemoveRange: xList[2] != 4");
|
||||
//Assert.AreEqual(5, xList[2], "List<int>.RemoveRange: xList[3] != 5");
|
||||
|
||||
//var xRange = xList.GetRange(1, 3);
|
||||
|
||||
//Assert.AreEqual(5, xRange[0], "List<int>.GetRange: xRange[0] != 5");
|
||||
//Assert.AreEqual(4, xRange[1], "List<int>.GetRange: xRange[1] != 4");
|
||||
//Assert.AreEqual(5, xRange[2], "List<int>.GetRange: xRange[2] != 5");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
using XSharp.Assembler;
|
||||
using Cosmos.IL2CPU.API;
|
||||
using XSharp;
|
||||
using CPUx86 = XSharp.Assembler.x86;
|
||||
using XSharp.Assembler;
|
||||
using XSharp.Assembler.x86;
|
||||
using static XSharp.XSRegisters;
|
||||
|
||||
namespace Cosmos.Core_Asm
|
||||
{
|
||||
public class ArrayInternalCopyAsm : AssemblerMethod
|
||||
{
|
||||
private const int SourceArrayDisplacement = 36;
|
||||
private const int SourceIndexDisplacement = 32;
|
||||
private const int SourceIndexDisplacement = 28;
|
||||
private const int DestinationArrayDisplacement = 24;
|
||||
private const int DestinationIndexDisplacement = 16;
|
||||
private const int LengthDisplacement = 12;
|
||||
|
|
@ -24,40 +25,152 @@ namespace Cosmos.Core_Asm
|
|||
|
||||
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
|
||||
{
|
||||
var xArrayCopyReverseLabel = "ArrayCopy_Reverse";
|
||||
var xArrayCopyReverseLoopLabel = "ArrayCopy_Reverse_Loop";
|
||||
var xArrayCopyEndLabel = "ArrayCopy_End";
|
||||
|
||||
XS.Comment("Source");
|
||||
XS.Comment("Element size");
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // element size
|
||||
XS.Set(EAX, EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
XS.Comment("Source ptr");
|
||||
XS.Set(XSRegisters.EBX, XSRegisters.EBP, sourceDisplacement: SourceIndexDisplacement);
|
||||
XS.Multiply(XSRegisters.EBX);
|
||||
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
XS.Add(XSRegisters.ESI, XSRegisters.EAX); // source ptr
|
||||
XS.Set(EBX, EBP, sourceDisplacement: SourceIndexDisplacement);
|
||||
XS.Multiply(EBX);
|
||||
XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
XS.Set(ESI, EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
XS.Add(ESI, EAX); // source ptr
|
||||
|
||||
XS.Comment("Destination");
|
||||
XS.Comment("Element size");
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // element size
|
||||
XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
XS.Comment("Destination ptr");
|
||||
XS.Set(XSRegisters.ECX, XSRegisters.EBP, sourceDisplacement: DestinationIndexDisplacement);
|
||||
XS.Multiply(XSRegisters.ECX);
|
||||
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(XSRegisters.EDI, XSRegisters.EAX); // destination ptr
|
||||
XS.Set(ECX, EBP, sourceDisplacement: DestinationIndexDisplacement);
|
||||
XS.Multiply(ECX);
|
||||
XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
XS.Set(EDI, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(EDI, EAX); // destination ptr
|
||||
|
||||
XS.Compare(EDI, ESI);
|
||||
XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel);
|
||||
|
||||
XS.Comment("Copy byte count");
|
||||
XS.Comment("Element size");
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // element size
|
||||
XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
XS.Comment("Count");
|
||||
XS.Set(XSRegisters.EDX, XSRegisters.EBP, sourceDisplacement: LengthDisplacement);
|
||||
XS.Multiply(XSRegisters.EDX);
|
||||
XS.Set(XSRegisters.ECX, XSRegisters.EAX);
|
||||
new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat };
|
||||
XS.Set(EDX, EBP, sourceDisplacement: LengthDisplacement);
|
||||
|
||||
// if length is 0, jump to end
|
||||
XS.Compare(EDX, 0);
|
||||
XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel);
|
||||
|
||||
XS.Multiply(EDX);
|
||||
XS.Set(ECX, EAX);
|
||||
|
||||
// if source and destination are equal, jump to end
|
||||
XS.Set(EAX, ESI);
|
||||
XS.Add(EAX, ECX);
|
||||
XS.Compare(EDI, EAX);
|
||||
XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel);
|
||||
XS.Jump(ConditionalTestEnum.LessThanOrEqualTo, xArrayCopyReverseLabel);
|
||||
|
||||
new Movs { Size = 8, Prefixes = InstructionPrefixes.Repeat };
|
||||
|
||||
XS.Jump(xArrayCopyEndLabel);
|
||||
|
||||
// source ptr + size >= destination ptr
|
||||
XS.Label(xArrayCopyReverseLabel);
|
||||
|
||||
XS.Comment("Array Reverse Copy: source ptr + size >= destination ptr");
|
||||
|
||||
XS.Add(ESI, ECX);
|
||||
XS.Add(EDI, ECX);
|
||||
|
||||
XS.Label(xArrayCopyReverseLoopLabel);
|
||||
|
||||
XS.Decrement(ESI);
|
||||
XS.Decrement(EDI);
|
||||
XS.Decrement(ECX);
|
||||
|
||||
XS.Set(AL, ESI, sourceIsIndirect: true);
|
||||
XS.Set(EDI, AL, destinationIsIndirect: true);
|
||||
|
||||
XS.Compare(ECX, 0);
|
||||
XS.Jump(ConditionalTestEnum.NotEqual, xArrayCopyReverseLoopLabel);
|
||||
|
||||
XS.Label(xArrayCopyEndLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Old implementation
|
||||
// (it's a good memcpy implementation, as it doesn't check for array overlapping, so it can't be used for Array.Copy)
|
||||
|
||||
//using Cosmos.Assembler;
|
||||
//using Cosmos.Assembler.x86;
|
||||
//using Cosmos.IL2CPU.API;
|
||||
//using XSharp.Common;
|
||||
//using static XSharp.Common.XSRegisters;
|
||||
|
||||
//namespace Cosmos.Core_Asm
|
||||
//{
|
||||
// public class ArrayInternalCopyAsm : AssemblerMethod
|
||||
// {
|
||||
// private const int SourceArrayDisplacement = 36;
|
||||
// private const int SourceIndexDisplacement = 28;
|
||||
// private const int DestinationArrayDisplacement = 24;
|
||||
// private const int DestinationIndexDisplacement = 16;
|
||||
// private const int LengthDisplacement = 12;
|
||||
|
||||
// /* void Copy(
|
||||
// * Array sourceArray, ebp + 36
|
||||
// * int sourceIndex, ebp + 28
|
||||
// * Array destinationArray, ebp + 24
|
||||
// * int destinationIndex, ebp + 16
|
||||
// * int length, ebp + 12
|
||||
// * bool reliable); ebp + 8
|
||||
// */
|
||||
|
||||
// public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
|
||||
// {
|
||||
// XS.Comment("Source");
|
||||
// XS.Comment("Element size");
|
||||
// XS.Set(EAX, EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
// XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
// XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
// XS.Comment("Source ptr");
|
||||
// XS.Set(EBX, EBP, sourceDisplacement: SourceIndexDisplacement);
|
||||
// XS.Multiply(EBX);
|
||||
// XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
// XS.Set(ESI, EBP, sourceDisplacement: SourceArrayDisplacement);
|
||||
// XS.Add(ESI, EAX); // source ptr
|
||||
|
||||
// XS.Comment("Destination");
|
||||
// XS.Comment("Element size");
|
||||
// XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
// XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
// XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
// XS.Comment("Destination ptr");
|
||||
// XS.Set(ECX, EBP, sourceDisplacement: DestinationIndexDisplacement);
|
||||
// XS.Multiply(ECX);
|
||||
// XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
|
||||
// XS.Set(EDI, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
// XS.Add(EDI, EAX); // destination ptr
|
||||
|
||||
// XS.Comment("Copy byte count");
|
||||
// XS.Comment("Element size");
|
||||
// XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
|
||||
// XS.Add(EAX, ObjectUtils.FieldDataOffset);
|
||||
// XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
|
||||
// XS.Comment("Count");
|
||||
// XS.Set(EDX, EBP, sourceDisplacement: LengthDisplacement);
|
||||
// XS.Multiply(EDX);
|
||||
// XS.Set(ECX, EAX);
|
||||
// new Movs { Size = 8, Prefixes = InstructionPrefixes.Repeat };
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ namespace Cosmos.Core_Asm
|
|||
private const int CountDisplacement = 8;
|
||||
|
||||
/*public static void BlockCopy(
|
||||
* Array src, [ebp + 24]
|
||||
* int srcOffset, [ebp + 20]
|
||||
* Array dst, [ebp + 16]
|
||||
* Array src, [ebp + 32]
|
||||
* int srcOffset, [ebp + 24]
|
||||
* Array dst, [ebp + 20]
|
||||
* int dstOffset, [ebp + 12]
|
||||
* int count); [ebp + 8]
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using static XSharp.XSRegisters;
|
|||
|
||||
namespace Cosmos.Core_Asm
|
||||
{
|
||||
//TODO: This asm refs Hardware.. should not.. its a higher ring
|
||||
public class CPUUpdateIDTAsm : AssemblerMethod
|
||||
{
|
||||
private static MethodBase GetMethodDef(Assembly aAssembly, string aType, string aMethodName, bool aErrorWhenNotFound)
|
||||
|
|
|
|||
Loading…
Reference in a new issue