using Internal.Text;
using Internal.TypeSystem;
+using ILCompiler.DependencyAnalysis.ARM;
+
namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
/// <summary>
{
protected override void EmitCode(NodeFactory factory, ref ARM.ARMEmitter instructionEncoder, bool relocsOnly)
{
- throw new NotImplementedException();
+ switch (_thunkKind)
+ {
+ case Kind.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 Kind.DelayLoadHelper:
+ case Kind.VirtualStubDispatch:
+ // r4 contains indirection cell
+ // push r4
+ instructionEncoder.EmitPUSH(Register.R4);
+ int index = _instanceCell.Table.IndexFromBeginningOfArray;
+ // mov r4, #index
+ instructionEncoder.EmitMOV(Register.R4, index);
+ // push r4
+ instructionEncoder.EmitPUSH(Register.R4);
+
+ // mov r4, [module]
+ instructionEncoder.EmitMOV(Register.R4, _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 Kind.Lazy:
+ // mov r1, [module]
+ instructionEncoder.EmitMOV(Register.R1, _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();
+ }
}
}
}