From 32bce706acb570308505802e548937918d780f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Sun, 16 Jul 2017 22:28:30 +0100 Subject: [PATCH 1/2] Array.Copy fix. Added List tests. --- .../System/Collections/Generic/ListTest.cs | 60 +++++-- .../Array/ArrayInternalCopyAsm.cs | 165 +++++++++++++++--- source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs | 1 - source/Cosmos.IL2CPU/ILOpCodes/OpBranch.cs | 5 + 4 files changed, 195 insertions(+), 36 deletions(-) diff --git a/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs b/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs index 1597474bd..225161e4f 100644 --- a/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs +++ b/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs @@ -2,33 +2,73 @@ 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 { + private static Debug.Kernel.Debugger mDebugger = new Debug.Kernel.Debugger("User", "ListTest"); public static void Execute() { var xList = new List(); + 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.Add: xList[0] != 0"); + Assert.AreEqual(1, xList[1], "List.Add: xList[1] != 1"); + Assert.AreEqual(2, xList[2], "List.Add: xList[2] != 2"); + + xList.Insert(2, 5); + + Assert.AreEqual(xList[0], 0, "List.Insert: xList[0] != 0"); + Assert.AreEqual(xList[1], 1, "List.Insert: xList[1] != 1"); + Assert.AreEqual(xList[2], 5, "List.Insert: xList[2] != 5"); + Assert.AreEqual(xList[3], 2, "List.Insert: xList[3] != 2"); + + xList.RemoveAt(1); + + Assert.AreEqual(xList[0], 0, "List.RemoveAt: xList[0] != 0"); + Assert.AreEqual(xList[1], 5, "List.RemoveAt: xList[1] != 5"); + Assert.AreEqual(xList[2], 2, "List.RemoveAt: xList[2] != 2"); + + //Commented tests depend on #583 + + //xList.AddRange(new List() { 3, 4, 5 }); + + //Assert.AreEqual(xList[0], 0, "List.AddRange: xList[0] != 0"); + //Assert.AreEqual(xList[1], 5, "List.AddRange: xList[1] != 5"); + //Assert.AreEqual(xList[2], 2, "List.AddRange: xList[2] != 2"); + //Assert.AreEqual(xList[2], 3, "List.AddRange: xList[3] != 3"); + //Assert.AreEqual(xList[2], 4, "List.AddRange: xList[4] != 4"); + //Assert.AreEqual(xList[2], 5, "List.AddRange: xList[5] != 5"); + + //xList.RemoveRange(2, 2); + + //Assert.AreEqual(xList[0], 0, "List.RemoveRange: xList[0] != 0"); + //Assert.AreEqual(xList[1], 5, "List.RemoveRange: xList[1] != 5"); + //Assert.AreEqual(xList[2], 4, "List.RemoveRange: xList[2] != 4"); + //Assert.AreEqual(xList[2], 5, "List.RemoveRange: xList[3] != 5"); + + //var xRange = xList.GetRange(1, 3); + + //Assert.AreEqual(xRange[0], 5, "List.GetRange: xRange[0] != 5"); + //Assert.AreEqual(xRange[1], 4, "List.GetRange: xRange[1] != 4"); + //Assert.AreEqual(xRange[2], 5, "List.GetRange: xRange[2] != 5"); 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.ToArray: xArray.Length != 3"); + Assert.AreEqual(0, xArray[0], "List.ToArray: xArray[0] != 0"); + Assert.AreEqual(1, xArray[1], "List.ToArray: xArray[1] != 1"); + Assert.AreEqual(2, xArray[2], "List.ToArray: xArray[2] != 2"); } } -} \ No newline at end of file +} diff --git a/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs b/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs index db452eb0a..01ac8df69 100644 --- a/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs +++ b/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs @@ -1,14 +1,15 @@ using Cosmos.Assembler; +using Cosmos.Assembler.x86; using Cosmos.IL2CPU.API; using XSharp.Common; -using CPUx86 = Cosmos.Assembler.x86; +using static XSharp.Common.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,154 @@ namespace Cosmos.Core_Asm public override void AssembleNew(Assembler.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 source and destination are equal, jump to end + XS.Compare(EDX, 0); + XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel); + + XS.Multiply(EDX); + XS.Set(ECX, EAX); + + XS.Compare(EDI, ESI); + XS.Jump(ConditionalTestEnum.GreaterThan, xArrayCopyReverseLabel); + + new Movs { Size = 8, Prefixes = InstructionPrefixes.Repeat }; + + XS.Jump(xArrayCopyEndLabel); + + // source ptr < destination ptr + XS.Label(xArrayCopyReverseLabel); + + XS.Comment("Array Reverse Copy: source ptr < destination ptr"); + XS.Comment("Element size"); + XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement); + XS.Add(EAX, ObjectUtils.FieldDataOffset); + XS.Set(EAX, EAX, sourceIsIndirect: true); // element size + + XS.Add(ESI, ECX); + XS.Add(EDI, ECX); + + XS.Sub(ESI, EAX); + XS.Sub(EDI, EAX); + + XS.Label(xArrayCopyReverseLoopLabel); + + XS.Set(AL, ESI, sourceIsIndirect: true); + XS.Set(EDI, AL, destinationIsIndirect: true); + + XS.Decrement(ESI); + XS.Decrement(EDI); + XS.Decrement(ECX); + + 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.IL2CPU.API; +//using XSharp.Common; +//using CPUx86 = Cosmos.Assembler.x86; + +//namespace Cosmos.Core_Asm +//{ +// public class ArrayInternalCopyAsm : AssemblerMethod +// { +// private const int SourceArrayDisplacement = 36; +// private const int SourceIndexDisplacement = 32; +// 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 CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; +// } +// } +//} diff --git a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs index 3d188a5ed..6a43c1d6a 100644 --- a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs +++ b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs @@ -8,7 +8,6 @@ using static XSharp.Common.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) diff --git a/source/Cosmos.IL2CPU/ILOpCodes/OpBranch.cs b/source/Cosmos.IL2CPU/ILOpCodes/OpBranch.cs index 7d2c0b4ef..2592bc9a0 100644 --- a/source/Cosmos.IL2CPU/ILOpCodes/OpBranch.cs +++ b/source/Cosmos.IL2CPU/ILOpCodes/OpBranch.cs @@ -171,6 +171,11 @@ namespace Cosmos.IL2CPU.ILOpCodes { { return; } + if (xValue1.GetTypeInfo().IsAssignableFrom(xValue2) + || xValue2.GetTypeInfo().IsAssignableFrom(xValue1)) + { + return; + } throw new Exception(String.Format("Comparing types '{0}' and '{1}' not supported!", xValue1.AssemblyQualifiedName, xValue2.AssemblyQualifiedName)); default: From c0c0884f5f2b7a70b9d8d6719d391bbe8c0dc707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Mon, 17 Jul 2017 19:48:21 +0100 Subject: [PATCH 2/2] Fixes. --- .../System/Collections/Generic/ListTest.cs | 76 +++++++++---------- .../Array/ArrayInternalCopyAsm.cs | 36 +++++---- .../Buffer/BufferBlockCopyAsm.cs | 6 +- source/Cosmos.IL2CPU/IL/Ldloc.cs | 2 +- 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs b/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs index 225161e4f..c3090a0c6 100644 --- a/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs +++ b/Tests/Cosmos.Compiler.Tests.Bcl/System/Collections/Generic/ListTest.cs @@ -9,8 +9,6 @@ namespace Cosmos.Compiler.Tests.Bcl.System.Collections.Generic { public static class ListTest { - private static Debug.Kernel.Debugger mDebugger = new Debug.Kernel.Debugger("User", "ListTest"); - public static void Execute() { var xList = new List(); @@ -26,49 +24,49 @@ namespace Cosmos.Compiler.Tests.Bcl.System.Collections.Generic Assert.AreEqual(1, xList[1], "List.Add: xList[1] != 1"); Assert.AreEqual(2, xList[2], "List.Add: xList[2] != 2"); - xList.Insert(2, 5); - - Assert.AreEqual(xList[0], 0, "List.Insert: xList[0] != 0"); - Assert.AreEqual(xList[1], 1, "List.Insert: xList[1] != 1"); - Assert.AreEqual(xList[2], 5, "List.Insert: xList[2] != 5"); - Assert.AreEqual(xList[3], 2, "List.Insert: xList[3] != 2"); - - xList.RemoveAt(1); - - Assert.AreEqual(xList[0], 0, "List.RemoveAt: xList[0] != 0"); - Assert.AreEqual(xList[1], 5, "List.RemoveAt: xList[1] != 5"); - Assert.AreEqual(xList[2], 2, "List.RemoveAt: xList[2] != 2"); - - //Commented tests depend on #583 - - //xList.AddRange(new List() { 3, 4, 5 }); - - //Assert.AreEqual(xList[0], 0, "List.AddRange: xList[0] != 0"); - //Assert.AreEqual(xList[1], 5, "List.AddRange: xList[1] != 5"); - //Assert.AreEqual(xList[2], 2, "List.AddRange: xList[2] != 2"); - //Assert.AreEqual(xList[2], 3, "List.AddRange: xList[3] != 3"); - //Assert.AreEqual(xList[2], 4, "List.AddRange: xList[4] != 4"); - //Assert.AreEqual(xList[2], 5, "List.AddRange: xList[5] != 5"); - - //xList.RemoveRange(2, 2); - - //Assert.AreEqual(xList[0], 0, "List.RemoveRange: xList[0] != 0"); - //Assert.AreEqual(xList[1], 5, "List.RemoveRange: xList[1] != 5"); - //Assert.AreEqual(xList[2], 4, "List.RemoveRange: xList[2] != 4"); - //Assert.AreEqual(xList[2], 5, "List.RemoveRange: xList[3] != 5"); - - //var xRange = xList.GetRange(1, 3); - - //Assert.AreEqual(xRange[0], 5, "List.GetRange: xRange[0] != 5"); - //Assert.AreEqual(xRange[1], 4, "List.GetRange: xRange[1] != 4"); - //Assert.AreEqual(xRange[2], 5, "List.GetRange: xRange[2] != 5"); - var xArray = xList.ToArray(); Assert.AreEqual(3, xArray.Length, "List.ToArray: xArray.Length != 3"); Assert.AreEqual(0, xArray[0], "List.ToArray: xArray[0] != 0"); Assert.AreEqual(1, xArray[1], "List.ToArray: xArray[1] != 1"); Assert.AreEqual(2, xArray[2], "List.ToArray: xArray[2] != 2"); + + xList.Insert(1, 5); + + Assert.AreEqual(0, xList[0], "List.Insert: xList[0] != 0"); + Assert.AreEqual(5, xList[1], "List.Insert: xList[1] != 5"); + Assert.AreEqual(1, xList[2], "List.Insert: xList[2] != 1"); + Assert.AreEqual(2, xList[3], "List.Insert: xList[3] != 2"); + + xList.RemoveAt(2); + + Assert.AreEqual(0, xList[0], "List.RemoveAt: xList[0] != 0"); + Assert.AreEqual(5, xList[1], "List.RemoveAt: xList[1] != 5"); + Assert.AreEqual(2, xList[2], "List.RemoveAt: xList[2] != 2"); + + // Commented tests depend on #583 + + //xList.AddRange(new List() { 3, 4, 5 }); + + //Assert.AreEqual(0, xList[0], "List.AddRange: xList[0] != 0"); + //Assert.AreEqual(5, xList[1], "List.AddRange: xList[1] != 5"); + //Assert.AreEqual(2, xList[2], "List.AddRange: xList[2] != 2"); + //Assert.AreEqual(3, xList[2], "List.AddRange: xList[3] != 3"); + //Assert.AreEqual(4, xList[2], "List.AddRange: xList[4] != 4"); + //Assert.AreEqual(5, xList[2], "List.AddRange: xList[5] != 5"); + + //xList.RemoveRange(2, 2); + + //Assert.AreEqual(0, xList[0], "List.RemoveRange: xList[0] != 0"); + //Assert.AreEqual(5, xList[1], "List.RemoveRange: xList[1] != 5"); + //Assert.AreEqual(4, xList[2], "List.RemoveRange: xList[2] != 4"); + //Assert.AreEqual(5, xList[2], "List.RemoveRange: xList[3] != 5"); + + //var xRange = xList.GetRange(1, 3); + + //Assert.AreEqual(5, xRange[0], "List.GetRange: xRange[0] != 5"); + //Assert.AreEqual(4, xRange[1], "List.GetRange: xRange[1] != 4"); + //Assert.AreEqual(5, xRange[2], "List.GetRange: xRange[2] != 5"); } } } diff --git a/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs b/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs index 01ac8df69..047f8be4c 100644 --- a/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs +++ b/source/Cosmos.Core_Asm/Array/ArrayInternalCopyAsm.cs @@ -64,44 +64,41 @@ namespace Cosmos.Core_Asm XS.Comment("Count"); XS.Set(EDX, EBP, sourceDisplacement: LengthDisplacement); - // If source and destination are equal, jump to end + // if length is 0, jump to end XS.Compare(EDX, 0); XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel); XS.Multiply(EDX); XS.Set(ECX, EAX); - XS.Compare(EDI, ESI); - XS.Jump(ConditionalTestEnum.GreaterThan, xArrayCopyReverseLabel); + // 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 < destination ptr + // source ptr + size >= destination ptr XS.Label(xArrayCopyReverseLabel); - XS.Comment("Array Reverse Copy: source ptr < destination ptr"); - 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("Array Reverse Copy: source ptr + size >= destination ptr"); XS.Add(ESI, ECX); XS.Add(EDI, ECX); - - XS.Sub(ESI, EAX); - XS.Sub(EDI, EAX); XS.Label(xArrayCopyReverseLoopLabel); - XS.Set(AL, ESI, sourceIsIndirect: true); - XS.Set(EDI, AL, destinationIsIndirect: true); - 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); @@ -112,18 +109,19 @@ namespace Cosmos.Core_Asm // 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 CPUx86 = Cosmos.Assembler.x86; +//using static XSharp.Common.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; @@ -172,7 +170,7 @@ namespace Cosmos.Core_Asm // XS.Set(EDX, EBP, sourceDisplacement: LengthDisplacement); // XS.Multiply(EDX); // XS.Set(ECX, EAX); -// new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; +// new Movs { Size = 8, Prefixes = InstructionPrefixes.Repeat }; // } // } //} diff --git a/source/Cosmos.Core_Asm/Buffer/BufferBlockCopyAsm.cs b/source/Cosmos.Core_Asm/Buffer/BufferBlockCopyAsm.cs index 3d1738e48..2978157b5 100644 --- a/source/Cosmos.Core_Asm/Buffer/BufferBlockCopyAsm.cs +++ b/source/Cosmos.Core_Asm/Buffer/BufferBlockCopyAsm.cs @@ -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] */ diff --git a/source/Cosmos.IL2CPU/IL/Ldloc.cs b/source/Cosmos.IL2CPU/IL/Ldloc.cs index 6c22d3b41..da375e2fa 100644 --- a/source/Cosmos.IL2CPU/IL/Ldloc.cs +++ b/source/Cosmos.IL2CPU/IL/Ldloc.cs @@ -26,7 +26,7 @@ namespace Cosmos.IL2CPU.X86.IL var xSize = SizeOfType(xVar.Type); bool xSigned = IsIntegerSigned(xVar.Type); - XS.Comment("Local type = " + xVar); + XS.Comment("Local type = " + xVar.Type); XS.Comment("Local EBP offset = " + xEBPOffset); XS.Comment("Local size = " + xSize);