|
// 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.Diagnostics;
using ILCompiler.DependencyAnalysis.ARM64;
namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
/// <summary>
/// This node emits a thunk calling DelayLoad_Helper with a given instance signature
/// to populate its indirection cell.
/// </summary>
public partial class ImportThunk : ISymbolNode
{
protected override void EmitCode(NodeFactory factory, ref ARM64Emitter instructionEncoder, bool relocsOnly)
{
if (_thunkKind == ImportThunkKind.Eager)
{
instructionEncoder.EmitJMP(_helperCell);
return;
}
if (relocsOnly)
{
// When doing relocs only, we don't need to generate the actual instructions
// as they will be ignored. Just emit the module import load and jump so we record the dependencies.
instructionEncoder.EmitADRP(Register.X1, factory.ModuleImport);
instructionEncoder.EmitLDR(Register.X1, Register.X1, factory.ModuleImport);
instructionEncoder.EmitJMP(_helperCell);
return;
}
switch (_thunkKind)
{
case ImportThunkKind.DelayLoadHelper:
case ImportThunkKind.DelayLoadHelperWithExistingIndirectionCell:
case ImportThunkKind.VirtualStubDispatch:
// x11 contains indirection cell
// Do nothing x11 contains our first param
// movz x9, #index
int index = _containingImportSection.IndexFromBeginningOfArray;
instructionEncoder.EmitMOV(Register.X9, checked((ushort)index));
// Move Module* -> x10
// adrp x10, ModuleImport
instructionEncoder.EmitADRP(Register.X10, factory.ModuleImport);
// ldr x10, [x10, ModuleImport page offset]
instructionEncoder.EmitLDR(Register.X10, Register.X10, factory.ModuleImport);
break;
case ImportThunkKind.Lazy:
// Move Module* -> x1
// adrp x1, ModuleImport
instructionEncoder.EmitADRP(Register.X1, factory.ModuleImport);
// ldr x1, [x1, ModuleImport page offset]
instructionEncoder.EmitLDR(Register.X1, Register.X1, factory.ModuleImport);
break;
default:
throw new NotImplementedException();
}
// branch to helper
instructionEncoder.EmitJMP(_helperCell);
}
}
}
|