diff --git a/source/Cosmos.IL2CPU.Tests/Cosmos.IL2CPU.Tests.csproj b/source/Cosmos.IL2CPU.Tests/Cosmos.IL2CPU.Tests.csproj
new file mode 100644
index 000000000..71d5e1bf8
--- /dev/null
+++ b/source/Cosmos.IL2CPU.Tests/Cosmos.IL2CPU.Tests.csproj
@@ -0,0 +1,90 @@
+
+
+
+ Debug
+ AnyCPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}
+ Library
+ Properties
+ Cosmos.IL2CPU.Tests
+ Cosmos.IL2CPU.Tests
+ v4.5
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
+ False
+ UnitTest
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {239e33a7-f0c3-4801-85ca-4d8f89a31dc0}
+ Cosmos.IL2CPU
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/Cosmos.IL2CPU.Tests/Plugs/System/BufferTests.cs b/source/Cosmos.IL2CPU.Tests/Plugs/System/BufferTests.cs
new file mode 100644
index 000000000..6674d496b
--- /dev/null
+++ b/source/Cosmos.IL2CPU.Tests/Plugs/System/BufferTests.cs
@@ -0,0 +1,81 @@
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using TargetClass = Cosmos.IL2CPU.X86.Plugs.CustomImplementations.System.Buffer;
+
+namespace Cosmos.IL2CPU.Tests.Plugs.System
+{
+ ///
+ /// Tests for the class plugs
+ ///
+ [TestClass]
+ public class BufferTests
+ {
+ ///
+ /// Verifies that non overlapped memory working.
+ ///
+ [TestMethod]
+ public unsafe void MemmoveNonOverlappedMemory()
+ {
+ byte[] src = new byte[10];
+ for (var i = 0; i < src.Length; i++)
+ {
+ src[i] = (byte)(i + 10);
+ }
+
+ byte[] dest = new byte[100];
+ dest[6] = 255;
+ fixed (byte* destPtr = dest, srcPtr = src)
+ {
+ TargetClass.__Memmove(destPtr, srcPtr, 5);
+ }
+
+ CollectionAssert.AreNotEquivalent(
+ new[] { 10, 11, 12, 13, 14, 0 },
+ dest.Take(6).ToArray());
+ }
+
+ ///
+ /// Verifies that overlapped memory regions working when copy forward
+ ///
+ [TestMethod]
+ public unsafe void MemmoveOverlappedMemory()
+ {
+ byte[] data = new byte[100];
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = (byte)(i + 10);
+ }
+
+ fixed (byte* destPtr = data, srcPtr = &data[1])
+ {
+ TargetClass.__Memmove(destPtr, srcPtr, 5);
+ }
+
+ CollectionAssert.AreNotEquivalent(
+ new[] { 11, 12, 13, 14, 15, 15, 16, 17, 18 },
+ data.Take(9).ToArray());
+ }
+
+ ///
+ /// Verifies that overlapped memory regions working when copy backward
+ ///
+ [TestMethod]
+ public unsafe void MemmoveOverlappedMemory2()
+ {
+ byte[] data = new byte[100];
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = (byte)(i + 10);
+ }
+
+ fixed (byte* destPtr = &data[1], srcPtr = data)
+ {
+ TargetClass.__Memmove(destPtr, srcPtr, 5);
+ }
+
+ CollectionAssert.AreNotEquivalent(
+ new [] { 10, 10, 11, 12, 13, 14, 16 },
+ data.Take(7).ToArray());
+ }
+ }
+}
diff --git a/source/Cosmos.IL2CPU.Tests/Properties/AssemblyInfo.cs b/source/Cosmos.IL2CPU.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..521529613
--- /dev/null
+++ b/source/Cosmos.IL2CPU.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Cosmos.IL2CPU.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Cosmos.IL2CPU.Tests")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a719fc5b-ddd5-46d0-9d22-e42d77b809f9")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/source/Cosmos.IL2CPU/ILOpCodes/OpSwitch.cs b/source/Cosmos.IL2CPU/ILOpCodes/OpSwitch.cs
index 42823c13b..b1df9ca34 100644
--- a/source/Cosmos.IL2CPU/ILOpCodes/OpSwitch.cs
+++ b/source/Cosmos.IL2CPU/ILOpCodes/OpSwitch.cs
@@ -63,6 +63,7 @@ namespace Cosmos.IL2CPU.ILOpCodes {
}
if (StackPopTypes[0] == typeof(int) ||
+ StackPopTypes[0] == typeof(uint) ||
StackPopTypes[0] == typeof(byte))
{
return;
diff --git a/source/Cosmos.IL2CPU/Plugs/System/Buffer.cs b/source/Cosmos.IL2CPU/Plugs/System/Buffer.cs
index fce0adff7..751e87496 100644
--- a/source/Cosmos.IL2CPU/Plugs/System/Buffer.cs
+++ b/source/Cosmos.IL2CPU/Plugs/System/Buffer.cs
@@ -13,6 +13,132 @@ namespace Cosmos.IL2CPU.X86.Plugs.CustomImplementations.System {
global::System.Buffer.BlockCopy((Array)(object)*src, 0, (Array)(object)*dest, 0, count);
}
+ ///
+ /// The memmove() function copies n bytes from memory area src to memory area dest.
+ /// The memory areas may overlap: copying takes place as though the bytes in src
+ /// are first copied into a temporary array that does not overlap src or dest,
+ /// and the bytes are then copied from the temporary array to dest.
+ ///
+ /// Destination address to copy data into.
+ /// Source address from where copy data.
+ /// Count of bytes to copy.
+ public static unsafe void __Memmove(byte* dest, byte* src, uint count)
+ {
+ uint t;
+ const int wmask = 0xFFFF;
+ const int wsize = 2;
+
+ /* nothing to do */
+ if (count == 0 || dest == src)
+ {
+ return;
+ }
+
+ if ((ulong)dest < (ulong)src)
+ {
+ /* Copy forward. */
+ t = (uint)src;
+
+ /* only need low bits */
+ if (((t | (uint)dest) & wmask) != 0)
+ {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((((t ^ (int)dest) & wmask) != 0) || (count < wsize))
+ t = count;
+ else
+ t = wsize - (t & wmask);
+ count -= t;
+ if (t != 0)
+ {
+ do { *dest++ = *src++; }
+ while (--t != 0);
+ }
+ }
+
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = count / wsize;
+ if (t != 0)
+ {
+ do
+ {
+ *(short*)dest = *(short*)src;
+ src += wsize;
+ dest += wsize;
+ }
+ while (--t != 0);
+ }
+
+ t = count & wmask;
+ if (t != 0)
+ {
+ do
+ {
+ dest++;
+ src++;
+ *dest = *src;
+ }
+ while (--t != 0);
+ }
+ }
+ else
+ {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += count;
+ dest += count;
+ t = (uint)src;
+ if (((t | (uint)dest) & wmask) != 0)
+ {
+ if (((t ^ (uint)dest) & wmask) != 0 || count <= wsize)
+ t = count;
+ else
+ t &= wmask;
+ count -= t;
+ if (t != 0)
+ {
+ do
+ {
+ --dest;
+ --src;
+ *dest = *src;
+ }
+ while (--t != 0);
+ }
+ }
+ t = count / wsize;
+ if (t != 0)
+ {
+ do
+ {
+ src -= wsize;
+ dest -= wsize;
+ *(ushort*)dest = *(ushort*)src;
+ }
+ while (--t != 0);
+ }
+
+ t = count & wmask;
+ if (t != 0)
+ {
+ do
+ {
+ --dest;
+ --src;
+ *dest = *src;
+ }
+ while (--t != 0);
+ }
+ }
+ }
+
[PlugMethod(Assembler = typeof(Assemblers.Buffer_BlockCopy))]
public static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count) {
}
diff --git a/source/Cosmos.sln b/source/Cosmos.sln
index 21f13a80d..6c87052b9 100644
--- a/source/Cosmos.sln
+++ b/source/Cosmos.sln
@@ -203,6 +203,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IL2CPU", "IL2CPU\IL2CPU.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaygroundCore", "..\Users\Matthijs\PlaygroundCore\PlaygroundCore.csproj", "{AB869246-4887-4117-851D-766EB9FF1E29}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.IL2CPU.Tests", "Cosmos.IL2CPU.Tests\Cosmos.IL2CPU.Tests.csproj", "{17329379-67D5-45D2-8EF0-9C625C43E117}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -988,6 +990,18 @@ Global
{AB869246-4887-4117-851D-766EB9FF1E29}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{AB869246-4887-4117-851D-766EB9FF1E29}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{AB869246-4887-4117-851D-766EB9FF1E29}.Release|x86.ActiveCfg = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|Itanium.ActiveCfg = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|Any CPU.Build.0 = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|Itanium.ActiveCfg = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {17329379-67D5-45D2-8EF0-9C625C43E117}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1064,5 +1078,6 @@ Global
{7E059184-F2C5-4CC6-B86D-FA12590C3C40} = {F104F6BC-EF8E-4408-A786-D570D7565231}
{6128DEEB-D30F-4859-B60F-C36D5452F3E9} = {6A15C540-8278-4B9C-B890-FA57FB6AE6A6}
{AB869246-4887-4117-851D-766EB9FF1E29} = {A0073D91-D9D3-4A90-9845-10E5CDBA5511}
+ {17329379-67D5-45D2-8EF0-9C625C43E117} = {6A15C540-8278-4B9C-B890-FA57FB6AE6A6}
EndGlobalSection
EndGlobal