import thunks for ARM just from zapper (#21072)
authorYaroslav Yamshchikov <y.yamshchiko@samsung.com>
Fri, 31 Jan 2020 19:49:01 +0000 (22:49 +0300)
committerGitHub <noreply@github.com>
Fri, 31 Jan 2020 19:49:01 +0000 (11:49 -0800)
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_ARM/ImportThunk.cs

index d19ec12..52cf31c 100644 (file)
@@ -6,6 +6,8 @@ using System;
 using Internal.Text;
 using Internal.TypeSystem;
 
+using ILCompiler.DependencyAnalysis.ARM;
+
 namespace ILCompiler.DependencyAnalysis.ReadyToRun
 {
     /// <summary>
@@ -16,7 +18,59 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
     {
         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();
+            }
         }
     }
 }