// 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 Internal.Text; using Internal.TypeSystem; using ILCompiler.DependencyAnalysis.ARM; 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 { protected override void EmitCode(NodeFactory factory, ref ARM.ARMEmitter instructionEncoder, bool relocsOnly) { switch (_thunkKind) { case ImportThunkKind.Eager: // mov r12, [helper] instructionEncoder.EmitMOV(Register.R12, _helperCell); // ldr.w r12, [r12] instructionEncoder.EmitLDR(Register.R12, Register.R12, 0); // bx r12 instructionEncoder.EmitJMP(Register.R12); break; case ImportThunkKind.DelayLoadHelper: case ImportThunkKind.VirtualStubDispatch: case ImportThunkKind.DelayLoadHelperWithExistingIndirectionCell: // r4 contains indirection cell // push r4 instructionEncoder.EmitPUSH(Register.R4); if (!relocsOnly) { int index = _containingImportSection.IndexFromBeginningOfArray; // mov r4, #index instructionEncoder.EmitMOV(Register.R4, index); // push r4 instructionEncoder.EmitPUSH(Register.R4); } // mov r4, [module] instructionEncoder.EmitMOV(Register.R4, factory.ModuleImport); // ldr r4, [r4] instructionEncoder.EmitLDR(Register.R4, Register.R4); // push r4 instructionEncoder.EmitPUSH(Register.R4); // mov r4, [helper] instructionEncoder.EmitMOV(Register.R4, _helperCell); // ldr r4, [r4] instructionEncoder.EmitLDR(Register.R4, Register.R4); // bx r4 instructionEncoder.EmitJMP(Register.R4); break; case ImportThunkKind.Lazy: // mov r1, [module] instructionEncoder.EmitMOV(Register.R1, factory.ModuleImport); // ldr r1, [r1] instructionEncoder.EmitLDR(Register.R1, Register.R1); // mov r12, [helper] instructionEncoder.EmitMOV(Register.R12, _helperCell); // ldr.w r12, [r12] instructionEncoder.EmitLDR(Register.R12, Register.R12, 0); // bx r12 instructionEncoder.EmitJMP(Register.R12); break; default: throw new NotImplementedException(); } } } } |