-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RISC-V] Fix passing float and uint arguments in VM (#105021)
* Add tests * Fix passing float and uint arguments in VM * Change test lib name so it doesn't clash with managed DLL on Windows
- Loading branch information
Showing
7 changed files
with
281 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
project (PrimitiveABINative) | ||
include_directories(${INC_PLATFORM_DIR}) | ||
|
||
if(CLR_CMAKE_HOST_WIN32) | ||
set_source_files_properties(PrimitiveABI.c PROPERTIES COMPILE_OPTIONS /TC) # compile as C | ||
else() | ||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -Oz") | ||
endif() | ||
|
||
add_library (PrimitiveABINative SHARED PrimitiveABI.c) | ||
|
||
install (TARGETS PrimitiveABINative DESTINATION bin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <stdio.h> | ||
|
||
#ifdef _MSC_VER | ||
#define DLLEXPORT __declspec(dllexport) | ||
#else | ||
#define DLLEXPORT __attribute__((visibility("default"))) | ||
#endif // _MSC_VER | ||
|
||
DLLEXPORT int64_t Echo_ExtendedUint_RiscV(int a0, uint32_t a1) | ||
{ | ||
return (int32_t)a1; | ||
} | ||
|
||
DLLEXPORT int64_t Echo_ExtendedUint_OnStack_RiscV( | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, uint32_t stack0) | ||
{ | ||
return (int32_t)stack0; | ||
} | ||
|
||
DLLEXPORT double Echo_Float_RiscV(float fa0, float fa1) | ||
{ | ||
return fa1 + fa0; | ||
} | ||
|
||
DLLEXPORT double Echo_Float_InIntegerReg_RiscV( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, | ||
float a0) | ||
{ | ||
return a0 + fa7; | ||
} | ||
|
||
DLLEXPORT double Echo_Float_OnStack_RiscV( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, float stack0) | ||
{ | ||
return stack0 + fa7; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
using System.Runtime.CompilerServices; | ||
using Xunit; | ||
|
||
public static class Program | ||
{ | ||
#region ExtendedUint_RiscVTests | ||
[DllImport("PrimitiveABINative")] | ||
public static extern long Echo_ExtendedUint_RiscV(int a0, uint a1); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static long Echo_ExtendedUint_RiscV_Managed(int a0, uint a1) => unchecked((int)a1); | ||
|
||
[Fact] | ||
public static void Test_ExtendedUint_RiscV() | ||
{ | ||
const uint arg = 0xB1ED0C1Eu; | ||
const long ret = unchecked((int)arg); | ||
long managed = Echo_ExtendedUint_RiscV_Managed(0, arg); | ||
long native = Echo_ExtendedUint_RiscV(0, arg); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[Fact] | ||
public static void Test_ExtendedUint_ByReflection_RiscV() | ||
{ | ||
const uint arg = 0xB1ED0C1Eu; | ||
const long ret = unchecked((int)arg); | ||
long managed = (long)typeof(Program).GetMethod("Echo_ExtendedUint_RiscV_Managed").Invoke( | ||
null, new object[] {0, arg}); | ||
long native = (long)typeof(Program).GetMethod("Echo_ExtendedUint_RiscV").Invoke( | ||
null, new object[] {0, arg}); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[DllImport("PrimitiveABINative")] | ||
public static extern long Echo_ExtendedUint_OnStack_RiscV( | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, uint stack0); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static long Echo_ExtendedUint_OnStack_RiscV_Managed( | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, uint stack0) => unchecked((int)stack0); | ||
|
||
[Fact] | ||
public static void Test_ExtendedUint_OnStack_RiscV() | ||
{ | ||
const uint arg = 0xB1ED0C1Eu; | ||
const long ret = unchecked((int)arg); | ||
long managed = Echo_ExtendedUint_OnStack_RiscV_Managed(0, 0, 0, 0, 0, 0, 0, 0, arg); | ||
long native = Echo_ExtendedUint_OnStack_RiscV(0, 0, 0, 0, 0, 0, 0, 0, arg); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[Fact] | ||
public static void Test_ExtendedUint_OnStack_ByReflection_RiscV() | ||
{ | ||
const uint arg = 0xB1ED0C1Eu; | ||
const long ret = unchecked((int)arg); | ||
long managed = (long)typeof(Program).GetMethod("Echo_ExtendedUint_OnStack_RiscV_Managed").Invoke( | ||
null, new object[] {0, 0, 0, 0, 0, 0, 0, 0, arg}); | ||
long native = (long)typeof(Program).GetMethod("Echo_ExtendedUint_OnStack_RiscV").Invoke( | ||
null, new object[] {0, 0, 0, 0, 0, 0, 0, 0, arg}); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
#endregion | ||
|
||
#region Float_RiscVTests | ||
[DllImport("PrimitiveABINative")] | ||
public static extern double Echo_Float_RiscV(float fa0, float fa1); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static double Echo_Float_RiscV_Managed(float fa0, float fa1) => fa1; | ||
|
||
[Fact] | ||
public static void Test_Float_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = Echo_Float_RiscV_Managed(0f, arg); | ||
double native = Echo_Float_RiscV(0f, arg); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[Fact] | ||
public static void Test_Float_ByReflection_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = (double)typeof(Program).GetMethod("Echo_Float_RiscV_Managed").Invoke( | ||
null, new object[] {0f, arg}); | ||
double native = (double)typeof(Program).GetMethod("Echo_Float_RiscV").Invoke( | ||
null, new object[] {0f, arg}); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[DllImport("PrimitiveABINative")] | ||
public static extern double Echo_Float_InIntegerReg_RiscV( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, float a0); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static double Echo_Float_InIntegerReg_RiscV_Managed( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, float a0) => a0; | ||
|
||
[Fact] | ||
public static void Test_Float_InIntegerReg_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = Echo_Float_InIntegerReg_RiscV_Managed(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, arg); | ||
double native = Echo_Float_InIntegerReg_RiscV(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, arg); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[Fact] | ||
public static void Test_Float_InIntegerReg_ByReflection_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = (double)typeof(Program).GetMethod("Echo_Float_InIntegerReg_RiscV_Managed").Invoke( | ||
null, new object[] {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, arg}); | ||
double native = (double)typeof(Program).GetMethod("Echo_Float_InIntegerReg_RiscV").Invoke( | ||
null, new object[] {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, arg}); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[DllImport("PrimitiveABINative")] | ||
public static extern double Echo_Float_OnStack_RiscV( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, float stack0); | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static double Echo_Float_OnStack_RiscV_Managed( | ||
float fa0, float fa1, float fa2, float fa3, float fa4, float fa5, float fa6, float fa7, | ||
int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, float stack0) => stack0; | ||
|
||
[Fact] | ||
public static void Test_Float_OnStack_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = Echo_Float_OnStack_RiscV_Managed(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0, 0, 0, 0, 0, 0, 0, 0, arg); | ||
double native = Echo_Float_OnStack_RiscV(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0, 0, 0, 0, 0, 0, 0, 0, arg); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
|
||
[Fact] | ||
public static void Test_Float_OnStack_ByReflection_RiscV() | ||
{ | ||
const float arg = 3.14159f; | ||
const double ret = 3.14159f; | ||
double managed = (double)typeof(Program).GetMethod("Echo_Float_OnStack_RiscV_Managed").Invoke( | ||
null, new object[] {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0, 0, 0, 0, 0, 0, 0, 0, arg}); | ||
double native = (double)typeof(Program).GetMethod("Echo_Float_OnStack_RiscV").Invoke( | ||
null, new object[] {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0, 0, 0, 0, 0, 0, 0, 0, arg}); | ||
|
||
Assert.Equal(ret, managed); | ||
Assert.Equal(ret, native); | ||
} | ||
#endregion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<!-- Needed for CMakeProjectReference --> | ||
<RequiresProcessIsolation>true</RequiresProcessIsolation> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<DebugType>PdbOnly</DebugType> | ||
<Optimize>True</Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="PrimitiveABI.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<CMakeProjectReference Include="CMakeLists.txt" /> | ||
</ItemGroup> | ||
</Project> |