From 93ad54dbf6c36d7b5f8a4ee809617163fd5f1ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 1 Nov 2023 13:52:07 +0100 Subject: [PATCH] Very partial x86 Windows support in compiler --- .../ILCompiler.Compiler/Compiler/JitHelper.cs | 24 +++++++++++ .../Compiler/NodeMangler.cs | 5 +++ .../Compiler/RootingServiceProvider.cs | 3 ++ .../Compiler/WindowsNodeMangler.cs | 40 +++++++++++++++++++ .../JitInterface/CorInfoImpl.RyuJit.cs | 26 ++++++++++++ 5 files changed, 98 insertions(+) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 1eed47ef1383..18d87976335a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -73,15 +73,39 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, case ReadyToRunHelper.WriteBarrier_EAX: mangledName = "RhpAssignRefEAX"; break; + case ReadyToRunHelper.WriteBarrier_EBX: + mangledName = "RhpAssignRefEBX"; + break; case ReadyToRunHelper.WriteBarrier_ECX: mangledName = "RhpAssignRefECX"; break; + case ReadyToRunHelper.WriteBarrier_ESI: + mangledName = "RhpAssignRefESI"; + break; + case ReadyToRunHelper.WriteBarrier_EDI: + mangledName = "RhpAssignRefEDI"; + break; + case ReadyToRunHelper.WriteBarrier_EBP: + mangledName = "RhpAssignRefEBP"; + break; case ReadyToRunHelper.CheckedWriteBarrier_EAX: mangledName = "RhpCheckedAssignRefEAX"; break; + case ReadyToRunHelper.CheckedWriteBarrier_EBX: + mangledName = "RhpCheckedAssignRefEBX"; + break; case ReadyToRunHelper.CheckedWriteBarrier_ECX: mangledName = "RhpCheckedAssignRefECX"; break; + case ReadyToRunHelper.CheckedWriteBarrier_ESI: + mangledName = "RhpCheckedAssignRefESI"; + break; + case ReadyToRunHelper.CheckedWriteBarrier_EDI: + mangledName = "RhpCheckedAssignRefEDI"; + break; + case ReadyToRunHelper.CheckedWriteBarrier_EBP: + mangledName = "RhpCheckedAssignRefEBP"; + break; case ReadyToRunHelper.Box: case ReadyToRunHelper.Box_Nullable: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs index 72110ed895d5..c578452e071a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs @@ -26,5 +26,10 @@ public abstract class NodeMangler public abstract string ThreadStaticsIndex(TypeDesc type); public abstract string TypeGenericDictionary(TypeDesc type); public abstract string MethodGenericDictionary(MethodDesc method); + + public virtual string ExternMethod(string unmangledName, MethodDesc method) + { + return unmangledName; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs index f6b562421ff8..877c322ed166 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs @@ -30,7 +30,10 @@ public void AddCompilationRoot(MethodDesc method, string reason, string exportNa _rootAdder(methodEntryPoint, reason); if (exportName != null) + { + exportName = _factory.NameMangler.NodeMangler.ExternMethod(exportName, method); _factory.NodeAliases.Add(methodEntryPoint, exportName); + } if (canonMethod != method && method.HasInstantiation) _rootAdder(_factory.MethodGenericDictionary(method), reason); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs index ee4117679432..7e21cc44a2a5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs @@ -72,5 +72,45 @@ public override string MethodGenericDictionary(MethodDesc method) { return GenericDictionaryNamePrefix + NameMangler.GetMangledMethodName(method); } + + public override string ExternMethod(string unmangledName, MethodDesc method) + { + TargetDetails target = method.Context.Target; + if (target.Architecture != TargetArchitecture.X86) + return unmangledName; + + UnmanagedCallingConventions callConv; + if (method.IsPInvoke) + { + callConv = method.GetPInvokeMethodCallingConventions() & UnmanagedCallingConventions.CallingConventionMask; + } + else if (method.IsUnmanagedCallersOnly) + { + // HACK: Work around GetUnmanagedCallersOnlyMethodCallingConventions crashing on non-Ecma methoddesc + if (method is not Internal.TypeSystem.Ecma.EcmaMethod) + callConv = UnmanagedCallingConventions.Cdecl; + else + callConv = method.GetUnmanagedCallersOnlyMethodCallingConventions() & UnmanagedCallingConventions.CallingConventionMask; + } + else + { + Debug.Assert(method is Internal.TypeSystem.Ecma.EcmaMethod ecmaMethod && ecmaMethod.GetRuntimeExportName() != null); + callConv = UnmanagedCallingConventions.Cdecl; + } + + int signatureBytes = 0; + foreach (var p in method.Signature) + { + signatureBytes += AlignmentHelper.AlignUp(p.GetElementSize().AsInt, target.PointerSize); + } + + return callConv switch + { + UnmanagedCallingConventions.Stdcall => string.Concat("_", unmangledName, "@", signatureBytes.ToString()), + UnmanagedCallingConventions.Fastcall => string.Concat("@", unmangledName, "@", signatureBytes.ToString()), + UnmanagedCallingConventions.Cdecl => string.Concat("_", unmangledName), + _ => throw new System.NotImplementedException() + }; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 60de79950e5e..344a4c4929e0 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -506,15 +506,40 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EAX: id = ReadyToRunHelper.WriteBarrier_EAX; break; + case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EBX: + id = ReadyToRunHelper.WriteBarrier_EBX; + break; case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ECX: id = ReadyToRunHelper.WriteBarrier_ECX; break; + case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ESI: + id = ReadyToRunHelper.WriteBarrier_ESI; + break; + case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EDI: + id = ReadyToRunHelper.WriteBarrier_EDI; + break; + case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EBP: + id = ReadyToRunHelper.WriteBarrier_EBP; + break; + case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EAX: id = ReadyToRunHelper.CheckedWriteBarrier_EAX; break; + case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EBX: + id = ReadyToRunHelper.CheckedWriteBarrier_EBX; + break; case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ECX: id = ReadyToRunHelper.CheckedWriteBarrier_ECX; break; + case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ESI: + id = ReadyToRunHelper.CheckedWriteBarrier_ESI; + break; + case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EDI: + id = ReadyToRunHelper.CheckedWriteBarrier_EDI; + break; + case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EBP: + id = ReadyToRunHelper.CheckedWriteBarrier_EBP; + break; case CorInfoHelpFunc.CORINFO_HELP_ARRADDR_ST: id = ReadyToRunHelper.Stelem_Ref; @@ -1879,6 +1904,7 @@ private void getAddressOfPInvokeTarget(CORINFO_METHOD_STRUCT_* method, ref CORIN MethodDesc md = HandleToObject(method); string externName = _compilation.PInvokeILProvider.GetDirectCallExternName(md); + externName = _compilation.NodeFactory.NameMangler.NodeMangler.ExternMethod(externName, md); pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternSymbol(externName)); }