diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/AssemblyStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/AssemblyStubNode.cs
index 5f19994583f..dcc44a93748 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/AssemblyStubNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/AssemblyStubNode.cs
@@ -43,6 +43,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
return x86Emitter.Builder.ToObjectData();
case TargetArchitecture.ARM:
+ case TargetArchitecture.ARMEL:
ARM.ARMEmitter armEmitter = new ARM.ARMEmitter(factory);
EmitCode(factory, ref armEmitter, relocsOnly);
armEmitter.Builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
index afdf9bdeb20..c8a21f2fe69 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
@@ -11,12 +11,91 @@
namespace ILCompiler.DependencyAnalysis
{
- // ARM specific portions of ReadyToRunHelperNode
+ ///
+ /// ARM specific portions of ReadyToRunHelperNode
+ ///
partial class ReadyToRunHelperNode
{
+ private ExternSymbolNode NYI_Assert;
protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bool relocsOnly)
{
- throw new NotImplementedException();
+ NYI_Assert = new ExternSymbolNode("NYI_Assert");
+
+ switch (Id)
+ {
+ case ReadyToRunHelperId.NewHelper:
+ {
+ TypeDesc target = (TypeDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.VirtualCall:
+ {
+ MethodDesc targetMethod = (MethodDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.IsInstanceOf:
+ {
+ TypeDesc target = (TypeDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.CastClass:
+ {
+ TypeDesc target = (TypeDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.NewArr1:
+ {
+ TypeDesc target = (TypeDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.GetNonGCStaticBase:
+ {
+ MetadataType target = (MetadataType)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.GetThreadStaticBase:
+ {
+ MetadataType target = (MetadataType)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.GetGCStaticBase:
+ {
+ MetadataType target = (MetadataType)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.DelegateCtor:
+ {
+ DelegateCreationInfo target = (DelegateCreationInfo)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ case ReadyToRunHelperId.ResolveVirtualFunction:
+ {
+ MethodDesc targetMethod = (MethodDesc)Target;
+ encoder.EmitJMP(NYI_Assert);
+ }
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
}
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
index 93bbdd57e69..5e0fde4fa27 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
@@ -19,17 +19,9 @@ public struct TargetRegisterMap
public TargetRegisterMap(TargetOS os)
{
- switch (os)
- {
- case TargetOS.Windows:
- Arg0 = Register.R0;
- Arg1 = Register.R1;
- Result = Register.R0;
- break;
-
- default:
- throw new NotImplementedException();
- }
+ Arg0 = Register.R0;
+ Arg1 = Register.R1;
+ Result = Register.R0;
}
}
}
diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs
index 385670960a9..8869e3d9d07 100644
--- a/src/ILCompiler/src/Program.cs
+++ b/src/ILCompiler/src/Program.cs
@@ -28,7 +28,9 @@ internal class Program
private bool _generateFullDgmlLog;
private TargetArchitecture _targetArchitecture;
+ private string _targetArchitectureStr;
private TargetOS _targetOS;
+ private string _targetOSStr;
private OptimizationMode _optimizationMode;
private bool _enableDebugInfo;
private string _systemModuleName = "System.Private.CoreLib";
@@ -130,6 +132,9 @@ private ArgumentSyntax ParseCommandLine(string[] args)
syntax.DefineOptionList("codegenopt", ref _codegenOptions, "Define a codegen option");
syntax.DefineOptionList("rdxml", ref _rdXmlFilePaths, "RD.XML file(s) for compilation");
+ syntax.DefineOption("targetarch", ref _targetArchitectureStr, "Target architecture for cross compilation");
+ syntax.DefineOption("targetos", ref _targetOSStr, "Target OS for cross compilation");
+
syntax.DefineOption("singlemethodtypename", ref _singleMethodTypeName, "Single method compilation: name of the owning type");
syntax.DefineOption("singlemethodname", ref _singleMethodName, "Single method compilation: name of the method");
syntax.DefineOptionList("singlemethodgenericarg", ref _singleMethodGenericArgs, "Single method compilation: generic arguments to the method");
@@ -167,6 +172,36 @@ private int Run(string[] args)
if (_outputFilePath == null)
throw new CommandLineException("Output filename must be specified (/out )");
+ //
+ // Set target Architecture and OS
+ //
+ if (_targetArchitectureStr != null)
+ {
+ if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase))
+ _targetArchitecture = TargetArchitecture.X86;
+ else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase))
+ _targetArchitecture = TargetArchitecture.X64;
+ else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase))
+ _targetArchitecture = TargetArchitecture.ARM;
+ else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase))
+ _targetArchitecture = TargetArchitecture.ARMEL;
+ else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase))
+ _targetArchitecture = TargetArchitecture.ARM64;
+ else
+ throw new CommandLineException("Target architecture is not supported");
+ }
+ if (_targetOSStr != null)
+ {
+ if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase))
+ _targetOS = TargetOS.Windows;
+ else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase))
+ _targetOS = TargetOS.Linux;
+ else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase))
+ _targetOS = TargetOS.OSX;
+ else
+ throw new CommandLineException("Target OS is not supported");
+ }
+
//
// Initialize type system context
//
diff --git a/src/Native/Runtime/arm/InteropThunksHelpers.S b/src/Native/Runtime/arm/InteropThunksHelpers.S
new file mode 100644
index 00000000000..109718d38ba
--- /dev/null
+++ b/src/Native/Runtime/arm/InteropThunksHelpers.S
@@ -0,0 +1,37 @@
+// 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
+
+.syntax unified
+.thumb
+
+// TODO: Implement Arm support
+
+//
+// InteropNative_CommonStub
+//
+NESTED_ENTRY InteropNative_CommonStub, _TEXT, NoHandler
+#ifdef _DEBUG
+ bl C_FUNC(NYI_Assert)
+#endif
+NESTED_END InteropNative_CommonStub, _TEXT
+
+//
+// IntPtr InteropNative_GetCommonStubAddress()
+//
+LEAF_ENTRY InteropNative_GetCommonStubAddress, _TEXT
+#ifdef _DEBUG
+ bl C_FUNC(NYI_Assert)
+#endif
+LEAF_END InteropNative_GetCommonStubAddress, _TEXT
+
+//
+// IntPtr InteropNative_GetCurrentThunkContext()
+//
+LEAF_ENTRY InteropNative_GetCurrentThunkContext, _TEXT
+#ifdef _DEBUG
+ bl C_FUNC(NYI_Assert)
+#endif
+LEAF_END InteropNative_GetCurrentThunkContext, _TEXT
diff --git a/src/Native/Runtime/unix/PalRedhawkUnix.cpp b/src/Native/Runtime/unix/PalRedhawkUnix.cpp
index 1c2fa1d2b6a..22d59579f71 100644
--- a/src/Native/Runtime/unix/PalRedhawkUnix.cpp
+++ b/src/Native/Runtime/unix/PalRedhawkUnix.cpp
@@ -704,73 +704,41 @@ REDHAWK_PALEXPORT void PalPrintFatalError(const char* message)
write(STDERR_FILENO, message, sizeof(message));
}
+#ifdef __linux__
+size_t
+GetLogicalProcessorCacheSizeFromOS()
+{
+ size_t cacheSize = 0;
+
+#ifdef _SC_LEVEL1_DCACHE_SIZE
+ cacheSize = max(cacheSize, sysconf(_SC_LEVEL1_DCACHE_SIZE));
+#endif
+#ifdef _SC_LEVEL2_CACHE_SIZE
+ cacheSize = max(cacheSize, sysconf(_SC_LEVEL2_CACHE_SIZE));
+#endif
+#ifdef _SC_LEVEL3_CACHE_SIZE
+ cacheSize = max(cacheSize, sysconf(_SC_LEVEL3_CACHE_SIZE));
+#endif
+#ifdef _SC_LEVEL4_CACHE_SIZE
+ cacheSize = max(cacheSize, sysconf(_SC_LEVEL4_CACHE_SIZE));
+#endif
+ return cacheSize;
+}
+#endif
+
bool QueryCacheSize()
{
bool success = true;
g_cbLargestOnDieCache = 0;
#ifdef __linux__
- DIR* cpuDir = opendir("/sys/devices/system/cpu");
- if (cpuDir == nullptr)
- {
- ASSERT_UNCONDITIONALLY("opendir on /sys/devices/system/cpu failed\n");
- return false;
- }
-
- dirent* cpuEntry;
- // Process entries starting with "cpu" (cpu0, cpu1, ...) in the directory
- while (success && (cpuEntry = readdir(cpuDir)) != nullptr)
- {
- if ((strncmp(cpuEntry->d_name, "cpu", 3) == 0) && isdigit(cpuEntry->d_name[3]))
- {
- char cpuCachePath[64] = "/sys/devices/system/cpu/";
- strcat(cpuCachePath, cpuEntry->d_name);
- strcat(cpuCachePath, "/cache");
- DIR* cacheDir = opendir(cpuCachePath);
- if (cacheDir == nullptr)
- {
- success = false;
- break;
- }
-
- strcat(cpuCachePath, "/");
- int cpuCacheBasePathLength = strlen(cpuCachePath);
-
- dirent* cacheEntry;
- // For all entries in the directory
- while ((cacheEntry = readdir(cacheDir)) != nullptr)
- {
- if (strncmp(cacheEntry->d_name, "index", 5) == 0)
- {
- cpuCachePath[cpuCacheBasePathLength] = '\0';
- strcat(cpuCachePath, cacheEntry->d_name);
- strcat(cpuCachePath, "/size");
-
- int fd = open(cpuCachePath, O_RDONLY);
- if (fd < 0)
- {
- success = false;
- break;
- }
- char cacheSizeStr[16];
- int bytesRead = read(fd, cacheSizeStr, sizeof(cacheSizeStr) - 1);
- cacheSizeStr[bytesRead] = '\0';
-
- // Parse the cache size that is formatted as a number followed by the K letter
- char* lastChar;
- int cacheSize = strtol(cacheSizeStr, &lastChar, 10) * 1024;
- ASSERT(*lastChar == 'K');
- g_cbLargestOnDieCache = max(g_cbLargestOnDieCache, cacheSize);
-
- close(fd);
- }
- }
-
- closedir(cacheDir);
- }
- }
- closedir(cpuDir);
+ g_cbLargestOnDieCache = GetLogicalProcessorCacheSizeFromOS();
+#ifndef _ARM_
+ // TODO Some systems on arm does not give the info about cache sizes by this method so we need to find another way
+ if (g_cbLargestOnDieCache == 0)
+ success = false;
+#endif
#elif HAVE_SYSCTL
@@ -791,7 +759,7 @@ bool QueryCacheSize()
}
}
#else
-#error Don't know how to get cache size on this platform
+#error Do not know how to get cache size on this platform
#endif // __linux__
// TODO: implement adjusted cache size
diff --git a/tests/runtest.sh b/tests/runtest.sh
index d0e94309d0a..db39175b1a9 100755
--- a/tests/runtest.sh
+++ b/tests/runtest.sh
@@ -47,7 +47,7 @@ run_test_dir()
__extra_args="${__extra_args} /p:IlcMultiModule=true"
fi
- rm -rf ${__dir_path}/bin ${__dir_path}/obj
+ rm -rf ${__dir_path}/bin/${CoreRT_BuildArch} ${__dir_path}/obj/${CoreRT_BuildArch}
local __msbuild_dir=${CoreRT_TestRoot}/../Tools
diff --git a/tests/src/Simple/SimpleTest.targets b/tests/src/Simple/SimpleTest.targets
index ba0cd5cdc94..6168776ed43 100644
--- a/tests/src/Simple/SimpleTest.targets
+++ b/tests/src/Simple/SimpleTest.targets
@@ -40,4 +40,8 @@
+
+
+
+