summaryrefslogtreecommitdiff
path: root/tests/src/JIT
diff options
context:
space:
mode:
authorSejong Oh <sejooh@microsoft.com>2016-04-22 00:24:25 -0700
committerSejong Oh <sejooh@microsoft.com>2016-04-22 00:24:25 -0700
commit42f5b498a679f5e110d9b9b6dc54bde6677ee5b7 (patch)
treef38c04a8d99197f675071502655ab2ca35e06718 /tests/src/JIT
parent1ccd82e8ef39f3259888543905d1f40399037248 (diff)
parentdd4388c801e2fb6104a603cad0ab439d4053ae09 (diff)
downloadcoreclr-42f5b498a679f5e110d9b9b6dc54bde6677ee5b7.tar.gz
coreclr-42f5b498a679f5e110d9b9b6dc54bde6677ee5b7.tar.bz2
coreclr-42f5b498a679f5e110d9b9b6dc54bde6677ee5b7.zip
Merge pull request #4398 from sejongoh/vector3_testcase
Vector3 Interop tests
Diffstat (limited to 'tests/src/JIT')
-rwxr-xr-xtests/src/JIT/SIMD/CMakeLists.txt10
-rwxr-xr-xtests/src/JIT/SIMD/Vector3Interop.cs339
-rw-r--r--tests/src/JIT/SIMD/Vector3Interop_r.csproj53
-rw-r--r--tests/src/JIT/SIMD/Vector3Interop_ro.csproj53
-rwxr-xr-xtests/src/JIT/SIMD/Vector3TestNative.cpp281
-rw-r--r--tests/src/JIT/SIMD/project.json1
6 files changed, 737 insertions, 0 deletions
diff --git a/tests/src/JIT/SIMD/CMakeLists.txt b/tests/src/JIT/SIMD/CMakeLists.txt
new file mode 100755
index 0000000000..555703b920
--- /dev/null
+++ b/tests/src/JIT/SIMD/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 2.6)
+project (Vector3TestNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES Vector3TestNative.cpp )
+
+# add the executable
+add_library (Vector3TestNative SHARED ${SOURCES})
+
+# add the install targets
+install (TARGETS Vector3TestNative DESTINATION bin)
diff --git a/tests/src/JIT/SIMD/Vector3Interop.cs b/tests/src/JIT/SIMD/Vector3Interop.cs
new file mode 100755
index 0000000000..7ef77cd12c
--- /dev/null
+++ b/tests/src/JIT/SIMD/Vector3Interop.cs
@@ -0,0 +1,339 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+public struct DT
+{
+ public Vector3 a;
+ public Vector3 b;
+};
+
+[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+public struct ComplexDT
+{
+ public int iv;
+ public DT vecs;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public string str;
+ public Vector3 v3;
+};
+
+class PInvokeTest
+{
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern int nativeCall_PInvoke_CheckVector3Size();
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern float nativeCall_PInvoke_Vector3Arg(
+ int i,
+ Vector3 v1,
+ [MarshalAs(UnmanagedType.LPStr)] string s,
+ Vector3 v2);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern Vector3 nativeCall_PInvoke_Vector3Ret();
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern float nativeCall_PInvoke_Vector3Array(Vector3[] v_array);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern DT nativeCall_PInvoke_Vector3InStruct(DT d);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern void nativeCall_PInvoke_Vector3InComplexStruct(ref ComplexDT cdt);
+
+ public static bool test()
+ {
+
+ // Expected return value is 12 bytes.
+ if (nativeCall_PInvoke_CheckVector3Size() != 12)
+ {
+ Console.WriteLine("The size of native Vector3 type is not 12 bytes");
+ return false;
+ }
+
+ {
+ int iv = 123;
+ Vector3 v1 = new Vector3(1,2,3);
+ string str = "abcdefg";
+ Vector3 v2 = new Vector3(10,11,12);
+ // Expected return value = 1 + 2 + 3 + 10 + 11 + 12 = 39
+ if (nativeCall_PInvoke_Vector3Arg(iv, v1, str, v2) != 39)
+ {
+ Console.Write("PInvoke Vector3Arg test failed\n");
+ return false;
+ }
+ }
+
+ // JIT crashes with this testcase.
+ // Disabled temporarily.
+ // {
+ // // Expected return value = 1 + 2 + 3 = 6
+ // Vector3 ret = nativeCall_PInvoke_Vector3Ret();
+ // float sum = ret.X + ret.Y + ret.Z;
+ // if (sum != 6) {
+ // Console.WriteLine("PInvoke Vector3Ret test failed");
+ // return false;
+ // }
+ // }
+
+
+ {
+ Vector3[] v3_array = new Vector3[2];
+ v3_array[0].X = 1; v3_array[0].Y = 2; v3_array[0].Z = 3;
+ v3_array[1].X = 5; v3_array[1].Y = 6; v3_array[1].Z = 7;
+ // Expected resutn value = 1 + 2 + 3 + 5 + 6 + 7 = 24
+ if (nativeCall_PInvoke_Vector3Array(v3_array) != 24)
+ {
+ Console.WriteLine("PInvoke Vector3Array test failed");
+ return false;
+ }
+ }
+
+ {
+ DT data = new DT();
+ data.a = new Vector3(1,2,3);
+ data.b = new Vector3(5,6,7);
+ DT ret = nativeCall_PInvoke_Vector3InStruct(data);
+ // Expected return value = 2 + 3 + 4 + 6 + 7 + 8 = 30
+ float sum = ret.a.X + ret.a.Y + ret.a.Z + ret.b.X + ret.b.Y + ret.b.Z;
+ if (sum != 30)
+ {
+ Console.WriteLine("PInvoke Vector3InStruct test failed");
+ return false;
+ }
+ }
+
+ {
+ ComplexDT cdt = new ComplexDT();
+ cdt.iv = 99;
+ cdt.str = "arg_string";
+ cdt.vecs.a = new Vector3(1,2,3);
+ cdt.vecs.b = new Vector3(5,6,7);
+ cdt.v3 = new Vector3(10, 20, 30);
+
+ nativeCall_PInvoke_Vector3InComplexStruct(ref cdt);
+
+ Console.WriteLine(" Managed ival: {0}", cdt.iv);
+ Console.WriteLine(" Managed Vector3 v1: ({0} {1} {2})", cdt.vecs.a.X, cdt.vecs.a.Y, cdt.vecs.a.Z);
+ Console.WriteLine(" Managed Vector3 v2: ({0} {1} {2})", cdt.vecs.b.X, cdt.vecs.b.Y, cdt.vecs.b.Z);
+ Console.WriteLine(" Managed Vector3 v3: ({0} {1} {2})", cdt.v3.X, cdt.v3.Y, cdt.v3.Z);
+ Console.WriteLine(" Managed string arg: {0}", cdt.str);
+
+ // Expected return value = 2 + 3 + 4 + 6 + 7 + 8 + 11 + 12 + 13 = 93
+ float sum = cdt.vecs.a.X + cdt.vecs.a.Y + cdt.vecs.a.Z
+ + cdt.vecs.b.X + cdt.vecs.b.Y + cdt.vecs.b.Z
+ + cdt.v3.X + cdt.v3.Y + cdt.v3.Z;
+ if ((sum != 93) || (cdt.iv != 100) || (cdt.str.ToString() != "ret_string") )
+ {
+ Console.WriteLine("PInvoke Vector3InStruct test failed");
+ return false;
+ }
+ }
+
+ Console.WriteLine("All PInvoke testcases passed");
+ return true;
+ }
+}
+
+class RPInvokeTest
+{
+ public delegate void CallBackDelegate_RPInvoke_Vector3Arg(
+ int i,
+ Vector3 v1,
+ [MarshalAs(UnmanagedType.LPStr)] string s,
+ Vector3 v2);
+
+ public delegate Vector3 CallBackDelegate_RPInvoke_Vector3Ret();
+
+ public delegate void CallBackDelegate_RPInvoke_Vector3Array(
+ [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] Vector3[] v,
+ int size);
+
+ public delegate void CallBackDelegate_RPInvoke_Vector3InStruct(
+ DT v);
+
+ public delegate void CallBackDelegate_RPInvoke_Vector3InComplexStruct(
+ ref ComplexDT v);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern void nativeCall_RPInvoke_Vector3Arg(
+ CallBackDelegate_RPInvoke_Vector3Arg callBack);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern bool nativeCall_RPInvoke_Vector3Ret(
+ CallBackDelegate_RPInvoke_Vector3Ret callBack);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern void nativeCall_RPInvoke_Vector3Array(
+ CallBackDelegate_RPInvoke_Vector3Array callBack,
+ int v);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern void nativeCall_RPInvoke_Vector3InStruct(
+ CallBackDelegate_RPInvoke_Vector3InStruct callBack,
+ int v);
+
+ [DllImport(@"Vector3TestNative", CallingConvention = CallingConvention.StdCall)]
+ public static extern bool nativeCall_RPInvoke_Vector3InComplexStruct(
+ CallBackDelegate_RPInvoke_Vector3InComplexStruct callBack);
+
+ static bool result = false;
+
+ static void callBack_RPInvoke_Vector3Arg(
+ int i,
+ Vector3 v1,
+ [MarshalAs(UnmanagedType.LPStr)] string s,
+ Vector3 v2)
+ {
+ Vector3 tmp = new Vector3(2, 2, 2);
+
+ // sum = (1, 2, 3) dot (2, 2, 2) = 12
+ float sum0 = Vector3.Dot(v1, tmp);
+ // sum = (10, 20, 30) dot (2, 2, 2) = 20 + 40 + 60 = 120
+ float sum1 = Vector3.Dot(v2, tmp);
+
+ Console.WriteLine("callBack_RPInvoke_Vector3Arg:");
+ Console.WriteLine(" iVal {0}", i);
+ Console.WriteLine(" SumOfEles(v1) = {0} SumOfEles(v2) = {1}", sum0, sum1);
+ Console.WriteLine(" str {0}", s);
+
+ result = (sum0 == 12) && (sum1 == 120) && (s == "abcdefg") && (i == 123);
+ }
+
+ static Vector3 callBack_RPInvoke_Vector3Ret()
+ {
+ Vector3 tmp = new Vector3(1, 2, 3);
+ return tmp;
+ }
+
+ static void callBack_RPInvoke_Vector3Array(
+ [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] Vector3[] v,
+ int size)
+ {
+ Vector3 tmp = new Vector3(2, 2, 2);
+
+ // sum0 = (2,3,4) dot (2,2,2) = 4 + 6 + 8 = 18
+ float sum0 = Vector3.Dot(v[0], tmp);
+ // sum0 = (11,21,31) dot (2,2,2) = 22 + 42 + 62 = 126
+ float sum1 = Vector3.Dot(v[1], tmp);
+
+ Console.WriteLine("callBack_RPInvoke_Vector3Array: Sum0 = {0} Sum1 = {1}", sum0, sum1);
+
+ result = (sum0 == 18) && (sum1 == 126);
+ }
+
+
+ static void callBack_RPInvoke_Vector3InStruct(DT v)
+ {
+ Vector3 tmp = new Vector3(2, 2, 2);
+
+ // sum0 = (2,3,4) dot (2,2,2) = 4 + 6 + 8 = 18
+ float sum0 = Vector3.Dot(v.a, tmp);
+ // sum1 = (11,21,31) dot (2,2,2) = 22 + 42 + 62 = 126
+ float sum1 = Vector3.Dot(v.b, tmp);
+
+ Console.WriteLine("callBack_RPInvoke_Vector3InStruct: Sum0 = {0} Sum1 = {1}", sum0, sum1);
+
+ result = (sum0 == 18) && (sum1 == 126);
+ }
+
+ static void callBack_RPInvoke_Vector3InComplexStruct(ref ComplexDT arg)
+ {
+ ComplexDT ret;
+ Console.WriteLine("callBack_RPInvoke_Vector3InComplexStruct");
+ Console.WriteLine(" Arg ival: {0}", arg.iv);
+ Console.WriteLine(" Arg Vector3 v1: ({0} {1} {2})", arg.vecs.a.X, arg.vecs.a.Y, arg.vecs.a.Z);
+ Console.WriteLine(" Arg Vector3 v2: ({0} {1} {2})", arg.vecs.b.X, arg.vecs.b.Y, arg.vecs.b.Z);
+ Console.WriteLine(" Arg Vector3 v3: ({0} {1} {2})", arg.v3.X, arg.v3.Y, arg.v3.Z);
+ Console.WriteLine(" Arg string arg: {0}", arg.str);
+
+ arg.vecs.a.X = arg.vecs.a.X + 1;
+ arg.vecs.a.Y = arg.vecs.a.Y + 1;
+ arg.vecs.a.Z = arg.vecs.a.Z + 1;
+ arg.vecs.b.X = arg.vecs.b.X + 1;
+ arg.vecs.b.Y = arg.vecs.b.Y + 1;
+ arg.vecs.b.Z = arg.vecs.b.Z + 1;
+ arg.v3.X = arg.v3.X + 1;
+ arg.v3.Y = arg.v3.Y + 1;
+ arg.v3.Z = arg.v3.Z + 1;
+ arg.iv = arg.iv + 1;
+ arg.str = "ret_string";
+
+ Console.WriteLine(" Return ival: {0}", arg.iv);
+ Console.WriteLine(" Return Vector3 v1: ({0} {1} {2})", arg.vecs.a.X, arg.vecs.a.Y, arg.vecs.a.Z);
+ Console.WriteLine(" Return Vector3 v2: ({0} {1} {2})", arg.vecs.b.X, arg.vecs.b.Y, arg.vecs.b.Z);
+ Console.WriteLine(" Return Vector3 v3: ({0} {1} {2})", arg.v3.X, arg.v3.Y, arg.v3.Z);
+ Console.WriteLine(" Return string arg: {0}", arg.str);
+ float sum = arg.vecs.a.X + arg.vecs.a.Y + arg.vecs.a.Z
+ + arg.vecs.b.X + arg.vecs.b.Y + arg.vecs.b.Z
+ + arg.v3.X + arg.v3.Y + arg.v3.Z;
+ Console.WriteLine(" Sum of all return float scalar values = {0}", sum);
+ }
+
+ public static bool test() {
+ int x = 1;
+
+ nativeCall_RPInvoke_Vector3Arg(callBack_RPInvoke_Vector3Arg);
+ if (!result)
+ {
+ Console.WriteLine("RPInvoke Vector3Arg test failed");
+ return false;
+ }
+
+ result = nativeCall_RPInvoke_Vector3Ret(callBack_RPInvoke_Vector3Ret);
+ if (!result)
+ {
+ Console.WriteLine("RPInvoke Vector3Ret test failed");
+ return false;
+ }
+
+ nativeCall_RPInvoke_Vector3Array(callBack_RPInvoke_Vector3Array, x);
+ if (!result)
+ {
+ Console.WriteLine("RPInvoke Vector3Array test failed");
+ return false;
+ }
+
+ nativeCall_RPInvoke_Vector3InStruct(callBack_RPInvoke_Vector3InStruct, x);
+ if (!result)
+ {
+ Console.WriteLine("RPInvoke Vector3InStruct test failed");
+ return false;
+ }
+
+ result = nativeCall_RPInvoke_Vector3InComplexStruct(callBack_RPInvoke_Vector3InComplexStruct);
+ if (!result)
+ {
+ Console.WriteLine("RPInvoke Vector3InComplexStruct test failed");
+ return false;
+ }
+
+ Console.WriteLine("All RPInvoke testcases passed");
+ return true;
+ }
+}
+
+class Test
+{
+ public static int Main()
+ {
+
+ if (!PInvokeTest.test())
+ {
+ return 101;
+ }
+
+ if (!RPInvokeTest.test())
+ {
+ return 101;
+ }
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/SIMD/Vector3Interop_r.csproj b/tests/src/JIT/SIMD/Vector3Interop_r.csproj
new file mode 100644
index 0000000000..7eb82e589d
--- /dev/null
+++ b/tests/src/JIT/SIMD/Vector3Interop_r.csproj
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Vector3Interop.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ <ProjectReference Include="CMakeLists.txt" />
+ </ItemGroup>
+ <!-- <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>-->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/SIMD/Vector3Interop_ro.csproj b/tests/src/JIT/SIMD/Vector3Interop_ro.csproj
new file mode 100644
index 0000000000..7eb82e589d
--- /dev/null
+++ b/tests/src/JIT/SIMD/Vector3Interop_ro.csproj
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <None Include="$(JitPackagesConfigFileDirectory)threading+thread\project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Vector3Interop.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="project.json" />
+ <ProjectReference Include="CMakeLists.txt" />
+ </ItemGroup>
+ <!-- <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>-->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/SIMD/Vector3TestNative.cpp b/tests/src/JIT/SIMD/Vector3TestNative.cpp
new file mode 100755
index 0000000000..51b4b860e7
--- /dev/null
+++ b/tests/src/JIT/SIMD/Vector3TestNative.cpp
@@ -0,0 +1,281 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(__clang__)
+#define EXPORT(type) __attribute__((visibility("default"))) extern "C" type
+#elif defined(_MSC_VER)
+#define EXPORT(type) extern "C" __declspec(dllexport) type
+#else // defined(__clang__)
+#define EXPORT(type) type
+#endif // !defined(__clang__)
+
+#if !defined(_MSC_VER)
+#if __i386__
+#define __stdcall __attribute__((stdcall))
+#else // __i386__
+#define __stdcall
+#endif // !__i386__
+#endif // !defined(_MSC_VER)
+
+typedef struct _Vector3
+{
+ float x;
+ float y;
+ float z;
+} Vector3;
+
+typedef struct _DT
+{
+ Vector3 a;
+ Vector3 b;
+} DT;
+
+typedef struct _ComplexDT
+{
+ int iv;
+ DT vecs;
+ char str[256];
+ Vector3 v3;
+} ComplexDT;
+
+//
+// PInvoke native call for Vector3 size check
+//
+
+EXPORT(int) __stdcall nativeCall_PInvoke_CheckVector3Size()
+{
+ printf("nativeCall_PInvoke_CheckVector3Size: sizeof(Vector3) == %d\n", (int)sizeof(Vector3));
+ fflush(stdout);
+ return sizeof(Vector3);
+}
+
+//
+// PInvoke native call for Vector3 argument
+//
+
+EXPORT(float) __stdcall nativeCall_PInvoke_Vector3Arg(int i, Vector3 v1, char* s, Vector3 v2)
+{
+ float sum0 = v1.x + v1.y + v1.z;
+ float sum1 = v2.x + v2.y + v2.z;
+ printf("nativeCall_PInvoke_Vector3Arg:\n");
+ printf(" iVal %d\n", i);
+ printf(" sumOfEles(%f, %f, %f) = %f\n", v1.x, v1.y, v1.z, sum0);
+ printf(" str %s\n", s);
+ printf(" sumOfEles(%f, %f, %f) = %f\n", v2.x, v2.y, v2.z, sum1);
+ fflush(stdout);
+ if ((strncmp(s, "abcdefg", strnlen(s, 32)) != 0) || i != 123) {
+ return 0;
+ }
+ return sum0 + sum1;
+}
+
+//
+// PInvoke native call for Vector3 argument
+//
+
+EXPORT(Vector3) __stdcall nativeCall_PInvoke_Vector3Ret()
+{
+ Vector3 ret;
+ ret.x = 1;
+ ret.y = 2;
+ ret.z = 3;
+ float sum = ret.x + ret.y + ret.z;
+ printf("nativeCall_PInvoke_Vector3Ret:\n");
+ printf(" Return value: (%f, %f, %f)\n", ret.x, ret.y, ret.z);
+ printf(" Sum of return scalar values = %f\n", sum);
+ fflush(stdout);
+ return ret;
+}
+
+//
+// PInvoke native call for Vector3 array
+//
+
+EXPORT(float) __stdcall nativeCall_PInvoke_Vector3Array(Vector3* arr)
+{
+ float sum = 0.0;
+ printf("nativeCall_PInvoke_Vector3Array\n");
+ for (unsigned i = 0; i < 2; ++i)
+ {
+ Vector3* e = &arr[i];
+ printf(" arrEle[%d]: %f %f %f\n", i, e->x, e->y, e->z);
+ sum += e->x + e->y + e->z;
+ }
+ printf(" Sum = %f\n", sum);
+ fflush(stdout);
+ return sum;
+}
+
+//
+// PInvoke native call for Vector3 in struct
+//
+
+EXPORT(DT) __stdcall nativeCall_PInvoke_Vector3InStruct(DT data)
+{
+ printf("nativeCall_PInvoke_Vector3InStruct\n");
+ DT ret;
+ ret.a.x = data.a.x + 1;
+ ret.a.y = data.a.y + 1;
+ ret.a.z = data.a.z + 1;
+ ret.b.x = data.b.x + 1;
+ ret.b.y = data.b.y + 1;
+ ret.b.z = data.b.z + 1;
+ printf(" First struct memeber: (%f %f %f) -> (%f %f %f)\n",
+ data.a.x, data.a.y, data.a.z, ret.a.x, ret.a.y, ret.a.z);
+ printf(" Second struct member: (%f %f %f) -> (%f %f %f)\n",
+ data.b.x, data.b.y, data.b.z, ret.b.x, ret.b.y, ret.b.z);
+ float sum = ret.a.x + ret.a.y + ret.a.z + ret.b.x + ret.b.y + ret.b.z;
+ printf(" Sum of all return scalar values = %f\n", sum);
+ fflush(stdout);
+ return ret;
+}
+
+//
+// PInvoke native call for Vector3 in complex struct
+//
+
+EXPORT(void) __stdcall nativeCall_PInvoke_Vector3InComplexStruct(ComplexDT* arg)
+{
+ static const char* ret_str = "ret_string";
+ printf("nativeCall_PInvoke_Vector3InStruct\n");
+ printf(" Arg ival: %d\n", arg->iv);
+ printf(" Arg Vector3 v1: (%f %f %f)\n", arg->vecs.a.x, arg->vecs.a.y, arg->vecs.a.z);
+ printf(" Arg Vector3 v2: (%f %f %f)\n", arg->vecs.b.x, arg->vecs.b.y, arg->vecs.b.z);
+ printf(" Arg Vector3 v3: (%f %f %f)\n", arg->v3.x, arg->v3.y, arg->v3.z);
+ printf(" Arg string arg: %s\n", arg->str);
+
+
+ arg->vecs.a.x = arg->vecs.a.x + 1;
+ arg->vecs.a.y = arg->vecs.a.y + 1;
+ arg->vecs.a.z = arg->vecs.a.z + 1;
+ arg->vecs.b.x = arg->vecs.b.x + 1;
+ arg->vecs.b.y = arg->vecs.b.y + 1;
+ arg->vecs.b.z = arg->vecs.b.z + 1;
+ arg->v3.x = arg->v3.x + 1;
+ arg->v3.y = arg->v3.y + 1;
+ arg->v3.z = arg->v3.z + 1;
+ arg->iv = arg->iv + 1;
+ strncpy(arg->str, ret_str, strnlen("ret_str", 32));
+
+ printf(" Return ival: %d\n", arg->iv);
+ printf(" Return Vector3 v1: (%f %f %f)\n", arg->vecs.a.x, arg->vecs.a.y, arg->vecs.a.z);
+ printf(" Return Vector3 v2: (%f %f %f)\n", arg->vecs.b.x, arg->vecs.b.y, arg->vecs.b.z);
+ printf(" Return Vector3 v3: (%f %f %f)\n", arg->v3.x, arg->v3.y, arg->v3.z);
+ printf(" Return string arg: %s\n", arg->str);
+ float sum = arg->vecs.a.x + arg->vecs.a.y + arg->vecs.a.z
+ + arg->vecs.b.x + arg->vecs.b.y + arg->vecs.b.z
+ + arg->v3.x + arg->v3.y + arg->v3.z;
+ printf(" Sum of all return float scalar values = %f\n", sum);
+ fflush(stdout);
+}
+
+//
+// RPInvoke native call for Vector3 argument
+//
+typedef void (__stdcall *CallBack_RPInvoke_Vector3Arg)(int i, Vector3 v1, char* s, Vector3 v2);
+
+
+EXPORT(void) __stdcall nativeCall_RPInvoke_Vector3Arg(
+ CallBack_RPInvoke_Vector3Arg notify)
+{
+ int i = 123;
+ const static char* str = "abcdefg";
+ Vector3 v1, v2;
+ v1.x = 1; v1.y = 2; v1.z = 3;
+ v2.x = 10; v2.y = 20; v2.z = 30;
+ notify(i, v1, (char*)str, v2);
+}
+
+//
+// RPInvoke native call for Vector3 array
+//
+
+typedef Vector3 (__stdcall *CallBack_RPInvoke_Vector3Ret)();
+
+EXPORT(bool) __stdcall nativeCall_RPInvoke_Vector3Ret(
+ CallBack_RPInvoke_Vector3Ret notify)
+{
+ Vector3 ret = notify();
+ printf("nativeCall_RPInvoke_Vector3Ret: Return value (%f %f %f)\n",
+ ret.x, ret.y, ret.z);
+ fflush(stdout);
+ if (ret.x == 1 && ret.y == 2 && ret.z == 3) {
+ return true;
+ }
+ return false;
+}
+
+//
+// RPInvoke native call for Vector3 array
+//
+
+typedef void (__stdcall *CallBack_RPInvoke_Vector3Array)(Vector3* v, int size);
+
+static Vector3 arr[2];
+
+EXPORT(void) __stdcall nativeCall_RPInvoke_Vector3Array(
+ CallBack_RPInvoke_Vector3Array notify,
+ int a)
+{
+ arr[0].x = a + 1; arr[0].y = a + 2; arr[0].z = a + 3;
+ arr[1].x = a + 10; arr[1].y = a + 20; arr[1].z = a + 30;
+ notify(arr, 2);
+}
+
+//
+// RPInvoke native call for Vector3-in-struct test
+//
+
+typedef void (__stdcall *CallBack_RPInvoke_Vector3InStruct)(DT v);
+
+static DT v;
+
+EXPORT(void) __stdcall nativeCall_RPInvoke_Vector3InStruct(
+ CallBack_RPInvoke_Vector3InStruct notify,
+ int a)
+{
+ v.a.x = a + 1; v.a.y = a + 2; v.a.z = a + 3;
+ v.b.x = a + 10; v.b.y = a + 20; v.b.z = a + 30;
+ notify(v);
+}
+
+//
+// RPInvoke native call for complex Vector3-in-struct test
+//
+
+typedef bool (__stdcall *CallBack_RPInvoke_Vector3InComplexStruct)(ComplexDT* v);
+
+EXPORT(bool) __stdcall nativeCall_RPInvoke_Vector3InComplexStruct(
+ CallBack_RPInvoke_Vector3InComplexStruct notify)
+{
+ static ComplexDT cdt;
+ cdt.iv = 99;
+ strncpy(cdt.str, "arg_string", strnlen("arg_string", 32));
+ cdt.vecs.a.x = 1; cdt.vecs.a.y = 2; cdt.vecs.a.z = 3;
+ cdt.vecs.b.x = 5; cdt.vecs.b.y = 6; cdt.vecs.b.z = 7;
+ cdt.v3.x = 10; cdt.v3.y = 20; cdt.v3.z = 30;
+
+ notify(&cdt);
+
+ printf(" Native ival: %d\n", cdt.iv);
+ printf(" Native Vector3 v1: (%f %f %f)\n", cdt.vecs.a.x, cdt.vecs.a.y, cdt.vecs.a.z);
+ printf(" Native Vector3 v2: (%f %f %f)\n", cdt.vecs.b.x, cdt.vecs.b.y, cdt.vecs.b.z);
+ printf(" Native Vector3 v3: (%f %f %f)\n", cdt.v3.x, cdt.v3.y, cdt.v3.z);
+ printf(" Native string arg: %s\n", cdt.str);
+ fflush(stdout);
+
+ // Expected return value = 2 + 3 + 4 + 6 + 7 + 8 + 11 + 12 + 13 = 93
+ float sum = cdt.vecs.a.x + cdt.vecs.a.y + cdt.vecs.a.z
+ + cdt.vecs.b.x + cdt.vecs.b.y + cdt.vecs.b.z
+ + cdt.v3.x + cdt.v3.y + cdt.v3.z;
+
+ if ((sum != 93) || (cdt.iv != 100) || (strcmp(cdt.str, "ret_string")!=0) )
+ {
+ return false;
+ }
+ return true;
+}
diff --git a/tests/src/JIT/SIMD/project.json b/tests/src/JIT/SIMD/project.json
index 5d474462db..8de132f98c 100644
--- a/tests/src/JIT/SIMD/project.json
+++ b/tests/src/JIT/SIMD/project.json
@@ -7,6 +7,7 @@
"System.Numerics.Vectors": "4.1.1-rc2-23816",
"System.Runtime": "4.1.0-rc2-23816",
"System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
"System.Threading": "4.0.0",
"System.Threading.Thread": "4.0.0-rc2-23816"
},