Skip to content

Commit

Permalink
arm64
Browse files Browse the repository at this point in the history
  • Loading branch information
VSadov committed Apr 12, 2023
1 parent a752396 commit 723e2ec
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
helperEntrypoint = factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType);
}

// First arg: address of the TypeManager slot that provides the helper with
// Arg0: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, factory.Target.PointerSize);

// Arg1: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used
// for initialization on first access).
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1);

// Second arg: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1, factory.Target.PointerSize);
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1);

encoder.EmitJMP(helperEntrypoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,13 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
helperEntrypoint = factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType);
}

// First arg: address of the TypeManager slot that provides the helper with
// Arg0: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, factory.Target.PointerSize);

// Arg1: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used
// for initialization on first access).
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1);

// Second arg: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1, factory.Target.PointerSize);
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1);

encoder.EmitJMP(helperEntrypoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,61 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
case ReadyToRunHelperId.GetThreadStaticBase:
{
MetadataType target = (MetadataType)Target;
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeThreadStaticIndex(target));
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.TypeThreadStaticIndex(target));

// First arg: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used
// for initialization on first access).
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg2);
// Arg0: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, factory.Target.PointerSize);

// Second arg: index of the type in the ThreadStatic section of the modules
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg2, factory.Target.PointerSize);
bool isSingleFile = factory.CompilationModuleGroup.IsSingleFileCompilation;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (isSingleFile)
{
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType));
ISymbolNode helper = factory.ExternSymbol("RhpGetThreadStaticBaseForType");
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
{
encoder.EmitJMP(helper);
}
else
{
// check if class is initialized
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));

encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitJE(helper);

// Arg1: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used for initialization on first access).
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1);
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase));
}
}
else
{
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));

encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitJE(factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType));

encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase));
ISymbolNode helper = factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType);

// Arg1: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used for initialization on first access).
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
{
encoder.EmitJMP(helper);
}
else
{
// check if class is initialized
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));

encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitJE(helper);

// call another helper (same arguments)
encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase));
}
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
helperEntrypoint = factory.HelperEntrypoint(HelperEntrypoint.GetThreadStaticBaseForType);
}

// First arg: address of the TypeManager slot that provides the helper with
// Arg0: index of the type in the ThreadStatic section of the modules
encoder.EmitLD(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, factory.Target.PointerSize);

// Arg1: address of the TypeManager slot that provides the helper with
// information about module index and the type manager instance (which is used
// for initialization on first access).
encoder.EmitLD(encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, 0);

// Second arg: index of the type in the ThreadStatic section of the modules
encoder.EmitLD(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1, factory.Target.PointerSize);
encoder.EmitLD(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg1, 0);

encoder.EmitJMP(helperEntrypoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter enc

case ReadyToRunHelperId.GetThreadStaticBase:
{
// TODO: VS will have to fix this too for the final shape of the helpers
MetadataType target = (MetadataType)Target;
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeThreadStaticIndex(target));

Expand Down

0 comments on commit 723e2ec

Please sign in to comment.