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 @@ + + + +