{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/coreclr/pulls/comments/25235778","id":25235778,"diff_hunk":"@@ -0,0 +1,567 @@\n+//\n+// Copyright (c) Microsoft. All rights reserved.\n+// Copyright (c) Geoff Norton. All rights reserved.\n+// Licensed under the MIT license. See LICENSE file in the project root for full license information. \n+//\n+\n+// ==++==\n+//\n+\n+//\n+// ==--==\n+\n+#include \"unixasmmacros.inc\"\n+#include \"asmconstants.h\"\n+\n+#ifdef FEATURE_MIXEDMODE\n+#define IJWNOADThunk__MakeCall        ?MakeCall@IJWNOADThunk@@KAXXZ \n+#define IJWNOADThunk__FindThunkTarget ?FindThunkTarget@IJWNOADThunk@@QEAAPEBXXZ\n+#endif\n+#define gfHostConfig                  ?g_fHostConfig@@3KA\n+#define NDirect__IsHostHookEnabled    ?IsHostHookEnabled@NDirect@@SAHXZ\n+\n+//\n+// METHODDESC_REGISTER: UMEntryThunk*\n+//\n+NESTED_ENTRY TheUMEntryPrestub, _TEXT, UMEntryPrestubUnwindFrameChainHandler\n+\n+#define TheUMEntryPrestub_XMM_SAVE_OFFSET SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES\n+\n+// Ensure that the new rsp will be 16-byte aligned.  Note that the caller has\n+// already pushed the return address.\n+#if (((SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES + SIZEOF_MAX_FP_ARG_SPILL) + 8) % 16) != 0\n+#define TheUMEntryPrestub_STACK_FRAME_SIZE (SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES + SIZEOF_MAX_FP_ARG_SPILL + 8)\n+#else\n+#define TheUMEntryPrestub_STACK_FRAME_SIZE (SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES + SIZEOF_MAX_FP_ARG_SPILL)\n+#endif\n+\n+        alloc_stack     TheUMEntryPrestub_STACK_FRAME_SIZE\n+\n+        save_reg_postrsp    rdi, TheUMEntryPrestub_STACK_FRAME_SIZE + 0x8\n+        save_reg_postrsp    rsi, TheUMEntryPrestub_STACK_FRAME_SIZE + 0x10\n+        save_reg_postrsp    rdx,  TheUMEntryPrestub_STACK_FRAME_SIZE + 0x18\n+        save_reg_postrsp    rcx,  TheUMEntryPrestub_STACK_FRAME_SIZE + 0x20\n+\n+        save_xmm128_postrsp xmm0, TheUMEntryPrestub_XMM_SAVE_OFFSET\n+        save_xmm128_postrsp xmm1, TheUMEntryPrestub_XMM_SAVE_OFFSET + 0x10\n+        save_xmm128_postrsp xmm2, TheUMEntryPrestub_XMM_SAVE_OFFSET + 0x20\n+        save_xmm128_postrsp xmm3, TheUMEntryPrestub_XMM_SAVE_OFFSET + 0x30\n+\n+        END_PROLOGUE\n+\n+        //\n+        // Do prestub-specific stuff\n+        //\n+        mov             rdi, METHODDESC_REGISTER\n+        call            C_FUNC(TheUMEntryPrestubWorker)\n+\n+        //\n+        // we're going to tail call to the exec stub that we just setup\n+        //\n+\n+        mov             rdi, [rsp + TheUMEntryPrestub_STACK_FRAME_SIZE + 8h]\n+        mov             rsi, [rsp + TheUMEntryPrestub_STACK_FRAME_SIZE + 10h]\n+        mov             rdx,  [rsp + TheUMEntryPrestub_STACK_FRAME_SIZE + 18h]\n+        mov             rcx,  [rsp + TheUMEntryPrestub_STACK_FRAME_SIZE + 20h]\n+\n+        movdqa          xmm0, [rsp + TheUMEntryPrestub_XMM_SAVE_OFFSET]\n+        movdqa          xmm1, [rsp + TheUMEntryPrestub_XMM_SAVE_OFFSET + 10h]\n+        movdqa          xmm2, [rsp + TheUMEntryPrestub_XMM_SAVE_OFFSET + 20h]\n+        movdqa          xmm3, [rsp + TheUMEntryPrestub_XMM_SAVE_OFFSET + 30h]\n+\n+        //\n+        // epilogue\n+        //\n+        add             rsp, TheUMEntryPrestub_STACK_FRAME_SIZE\n+        TAILJMP_RAX\n+        \n+NESTED_END TheUMEntryPrestub, _TEXT\n+\n+\n+//\n+// METHODDESC_REGISTER: UMEntryThunk*\n+//\n+NESTED_ENTRY UMThunkStub, _TEXT, UMThunkStubUnwindFrameChainHandler\n+\n+// number of integer registers saved in prologue\n+#define UMThunkStubAMD64_NUM_REG_PUSHES 2\n+\n+// rare path spill area\n+#define UMThunkStubAMD64_RARE_PATH_SPILL_SIZE 0x10\n+#define UMThunkStubAMD64_RARE_PATH_SPILL_NEGOFFSET 0x20\n+\n+// HOST_NOTIFY_FLAG\n+#define UMThunkStubAMD64_HOST_NOTIFY_FLAG_NEGOFFSET 0x28\n+\n+// XMM save area \n+#define UMThunkStubAMD64_XMM_SAVE_NEGOFFSET 0x68\n+\n+// Add in the callee scratch area size.\n+#define UMThunkStubAMD64_CALLEE_SCRATCH_SIZE SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES\n+#define UMThunkStubAMD64_STACK_FRAME_SIZE 0x88\n+\n+// Now we have the full size of the stack frame.  The offsets have been computed relative to the\n+// top, so negate them to make them relative to the post-prologue rsp.\n+#define UMThunkStubAMD64_FRAME_OFFSET UMThunkStubAMD64_CALLEE_SCRATCH_SIZE\n+#define UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET (UMThunkStubAMD64_STACK_FRAME_SIZE - UMThunkStubAMD64_FRAME_OFFSET - UMThunkStubAMD64_RARE_PATH_SPILL_NEGOFFSET)\n+#define UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET (UMThunkStubAMD64_STACK_FRAME_SIZE - UMThunkStubAMD64_FRAME_OFFSET - UMThunkStubAMD64_HOST_NOTIFY_FLAG_NEGOFFSET)\n+#define UMThunkStubAMD64_XMM_SAVE_OFFSET (UMThunkStubAMD64_STACK_FRAME_SIZE - UMThunkStubAMD64_FRAME_OFFSET - UMThunkStubAMD64_XMM_SAVE_NEGOFFSET)\n+#define UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET (UMThunkStubAMD64_STACK_FRAME_SIZE + 8 - UMThunkStubAMD64_FRAME_OFFSET)\n+#define UMThunkStubAMD64_FIXED_STACK_ALLOC_SIZE (UMThunkStubAMD64_STACK_FRAME_SIZE - (UMThunkStubAMD64_NUM_REG_PUSHES * 8))\n+\n+#if (UMTHUNKSTUB_HOST_NOTIFY_FLAG_RBPOFFSET - UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET) != 0\n+#error update UMTHUNKSTUB_HOST_NOTIFY_FLAG_RBPOFFSET\n+#endif\n+\n+//\n+// [ callee scratch ]            <-- new RSP\n+// [ callee scratch ]\n+// [ callee scratch ]\n+// [ callee scratch ]\n+// {optional stack args passed to callee}\n+// xmm0                          <-- RBP\n+// xmm1\n+// xmm2\n+// xmm3\n+// {optional padding to align xmm regs}\n+// HOST_NOTIFY_FLAG (needs to make ReverseLeaveRuntime call flag)\n+// [rare path spill area]\n+// [rare path spill area]\n+// rbp save\n+// r12 save\n+// return address                <-- entry RSP\n+// [rcx home]\n+// [rdx home]\n+// [r8 home]\n+// [r9 home]\n+// stack arg 0\n+// stack arg 1\n+// ...\n+\n+        push_nonvol_reg r12\n+        push_nonvol_reg rbp                                                                     // stack_args\n+        alloc_stack     UMThunkStubAMD64_FIXED_STACK_ALLOC_SIZE\n+        set_frame       rbp, UMThunkStubAMD64_FRAME_OFFSET                                      // stack_args\n+        mov             byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 0            // hosted\n+        END_PROLOGUE\n+\n+        //\n+        // Call GetThread()\n+        //\n+        call            C_FUNC(GetThread)                          // will not trash r10\n+        test            rax, rax\n+        jz              LOCAL_LABEL(DoThreadSetup)\n+\n+LOCAL_LABEL(HaveThread):\n+\n+        mov             r12, rax                // r12 <- Thread*\n+\n+        //\n+        // disable preemptive GC\n+        //\n+        mov             dword ptr [r12 + OFFSETOF__Thread__m_fPreemptiveGCDisabled], 1\n+\n+        //\n+        // catch returning thread here if a GC is in progress\n+        //\n+        cmp             [rip + C_FUNC(g_TrapReturningThreads)@GOTPCREL], 0\n+        jnz             LOCAL_LABEL(DoTrapReturningThreadsTHROW)\n+\n+LOCAL_LABEL(InCooperativeMode):\n+\n+#ifdef FEATURE_INCLUDE_ALL_INTERFACES\n+        test            [gfHostConfig], ASM_CLRTASKHOSTED    // inlined NDirect::IsHostHookEnabled       // hosted\n+#ifdef _DEBUG\n+        call            IsHostHookEnabledHelper\n+        test            eax, eax\n+#endif // _DEBUG\n+        jnz             LOCAL_LABEL(NotifyHost_ReverseEnterRuntime)                                                  // hosted\n+LOCAL_LABEL(Done_NotifyHost_ReverseEnterRuntime):\n+#endif\n+\n+        mov             rax, [r12 + OFFSETOF__Thread__m_pDomain]\n+        mov             eax, [rax + OFFSETOF__AppDomain__m_dwId]\n+\n+        mov             r11d, [METHODDESC_REGISTER + OFFSETOF__UMEntryThunk__m_dwDomainId]\n+\n+        cmp             rax, r11\n+        jne             LOCAL_LABEL(WrongAppDomain)\n+\n+        mov             r11, [METHODDESC_REGISTER + OFFSETOF__UMEntryThunk__m_pUMThunkMarshInfo]\n+        mov             eax, [r11 + OFFSETOF__UMThunkMarshInfo__m_cbActualArgSize]                      // stack_args\n+        test            rax, rax                                                                        // stack_args\n+        jnz             LOCAL_LABEL(UMThunkStub_CopyStackArgs)                                                                   // stack_args\n+        \n+LOCAL_LABEL(UMThunkStub_ArgumentsSetup):\n+\n+        mov             rax, [r11 + OFFSETOF__UMThunkMarshInfo__m_pILStub]                              // rax <- Stub*\n+        call            rax\n+\n+LOCAL_LABEL(PostCall):\n+        //\n+        // enable preemptive GC\n+        //\n+        mov             dword ptr [r12 + OFFSETOF__Thread__m_fPreemptiveGCDisabled], 0\n+\n+#ifdef FEATURE_INCLUDE_ALL_INTERFACES\n+        cmp             byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 0                    // hosted\n+        jnz             LOCAL_LABEL(NotifyHost_ReverseLeaveRuntime)                                                  // hosted\n+LOCAL_LABEL(Done_NotifyHost_ReverseLeaveRuntime):        \n+#endif\n+\n+        // epilog\n+        lea             rsp, [rbp - UMThunkStubAMD64_FRAME_OFFSET + UMThunkStubAMD64_FIXED_STACK_ALLOC_SIZE]\n+        pop             rbp                                                                             // stack_args\n+        pop             r12\n+        ret\n+\n+\n+LOCAL_LABEL(DoThreadSetup):\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rdi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h], rsi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], rdx\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h], rcx\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        //            initial measurements indidcate that this could be worth about a 5% savings in reverse\n+        //            pinvoke overhead.\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h], xmm0\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h], xmm1\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h], xmm2\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h], xmm3\n+\n+        mov             [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET], METHODDESC_REGISTER\n+        call            C_FUNC(CreateThreadBlockThrow)\n+        mov             METHODDESC_REGISTER, [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET]\n+\n+        mov             rdi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h] \n+        mov             rsi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h] \n+        mov             rdx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h] \n+        mov             rcx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h]\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        movdqa          xmm0, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h]\n+        movdqa          xmm1, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h]\n+        movdqa          xmm2, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h]\n+        movdqa          xmm3, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h]\n+        \n+        jmp             LOCAL_LABEL(HaveThread)\n+        \n+LOCAL_LABEL(DoTrapReturningThreadsTHROW):\n+\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rdi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h], rsi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], rdx\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h], rcx\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        //            initial measurements indidcate that this could be worth about a 5% savings in reverse\n+        //            pinvoke overhead.\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h], xmm0\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h], xmm1\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h], xmm2\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h], xmm3\n+\n+        mov             [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET], METHODDESC_REGISTER\n+        mov             rdi, r12                                                                  // Thread* pThread\n+        mov             rsi, METHODDESC_REGISTER                                                  // UMEntryThunk* pUMEntry\n+        call            C_FUNC(UMThunkStubRareDisableWorker)\n+        mov             METHODDESC_REGISTER, [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET]\n+\n+        mov             rdi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h] \n+        mov             rsi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h] \n+        mov             rdx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h] \n+        mov             rcx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h]\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        movdqa          xmm0, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h]\n+        movdqa          xmm1, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h]\n+        movdqa          xmm2, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h]\n+        movdqa          xmm3, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h]\n+\n+        jmp             LOCAL_LABEL(InCooperativeMode)\n+\n+LOCAL_LABEL(UMThunkStub_CopyStackArgs):\n+        // rax = cbStackArgs (with 20h for register args subtracted out already)\n+\n+        sub             rsp, rax\n+        and             rsp, -16\n+\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rdi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h], rsi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], rdx\n+\n+        // rax = number of bytes\n+\n+        lea             rdi, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES] \n+        lea             rsi, [rsp + UMThunkStubAMD64_CALLEE_SCRATCH_SIZE]\n+\n+LOCAL_LABEL(CopyLoop):\n+        // rax = number of bytes\n+        // rcx = src\n+        // rdx = dest\n+        // r8 = sratch\n+\n+        add             rax, -8\n+        mov             r8, [rdi + rax]\n+        mov             [rsi + rax], r8\n+        jnz             LOCAL_LABEL(CopyLoop)\n+\n+        mov             rdi, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h]\n+        mov             rsi, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h]\n+        mov             rdx, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h]\n+        \n+        jmp             LOCAL_LABEL(UMThunkStub_ArgumentsSetup)\n+\n+#ifdef FEATURE_INCLUDE_ALL_INTERFACES\n+LOCAL_LABEL(NotifyHost_ReverseEnterRuntime):\n+        mov             [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET], METHODDESC_REGISTER\n+\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rdi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h], rsi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], rdx\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h], rcx\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        //            initial measurements indidcate that this could be worth about a 5% savings in reverse\n+        //            pinvoke overhead.\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h], xmm0\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h], xmm1\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h], xmm2\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h], xmm3\n+\n+        mov             rdi, r12\n+        call            C_FUNC(ReverseEnterRuntimeHelper)\n+        mov             byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 1\n+                \n+        mov             rdi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h] \n+        mov             rsi,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h] \n+        mov             rdx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h] \n+        mov             rcx,   [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h]\n+\n+        // @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls\n+        movdqa          xmm0, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h]\n+        movdqa          xmm1, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h]\n+        movdqa          xmm2, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h]\n+        movdqa          xmm3, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h]\n+\n+        mov             METHODDESC_REGISTER, [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET]\n+\n+        jmp             LOCAL_LABEL(Done_NotifyHost_ReverseEnterRuntime)\n+\n+LOCAL_LABEL(NotifyHost_ReverseLeaveRuntime):\n+\n+        // save rax, xmm0\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rax\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h], xmm0\n+\n+        mov             rdi, r12\n+        call            C_FUNC(ReverseLeaveRuntimeHelper)\n+        mov             byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 0\n+\n+        // restore rax, xmm0\n+        mov             rax, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h]\n+        movdqa          xmm0, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h]\n+        \n+        jmp             LOCAL_LABEL(Done_NotifyHost_ReverseLeaveRuntime)\n+#endif\n+\n+LOCAL_LABEL(WrongAppDomain):\n+        //\n+        // home register args to the stack\n+        //\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h], rdi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  8h], rsi\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], rdx\n+        mov             [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h], rcx\n+\n+        //\n+        // save off xmm registers\n+        //\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h], xmm0\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h], xmm1\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h], xmm2\n+        movdqa          [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h], xmm3\n+\n+        //\n+        // call our helper to perform the AD transtion \n+        //\n+        mov             rdi, METHODDESC_REGISTER\n+        lea             r8,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET]\n+        mov             rax, [METHODDESC_REGISTER + OFFSETOF__UMEntryThunk__m_pUMThunkMarshInfo]\n+        mov             r9d, [rax + OFFSETOF__UMThunkMarshInfo__m_cbActualArgSize]\n+        call            C_FUNC(UM2MDoADCallBack)\n+\n+        // restore return value\n+        mov             rax,  [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h]\n+        movdqa          xmm0, [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET +  0h]\n+\n+        jmp             LOCAL_LABEL(PostCall)\n+\n+NESTED_END UMThunkStub, _TEXT\n+\n+//\n+// EXTERN_C void __stdcall UM2MThunk_WrapperHelper(\n+//       void *pThunkArgs,               // rdi\n+//       int argLen,                     // rsi\n+//       void *pAddr,                    // rdx            // not used\n+//       UMEntryThunk *pEntryThunk,      // rcx\n+//       Thread *pThread)//               // [entry_sp + 28h]\n+//\n+NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler\n+\n+// number of integer registers saved in prologue\n+#define UM2MThunk_WrapperHelper_NUM_REG_PUSHES 3\n+\n+#define UM2MThunk_WrapperHelper_CALLEE_SCRATCH_SIZE SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES\n+#define UM2MThunk_WrapperHelper_STACK_FRAME_SIZE 0x38\n+\n+#define UM2MThunk_WrapperHelper_FRAME_OFFSET UM2MThunk_WrapperHelper_CALLEE_SCRATCH_SIZE\n+#define UM2MThunk_WrapperHelper_FIXED_STACK_ALLOC_SIZE (UM2MThunk_WrapperHelper_STACK_FRAME_SIZE - (UM2MThunk_WrapperHelper_NUM_REG_PUSHES * 8))\n+\n+        push_nonvol_reg r8\n+        push_nonvol_reg r9\n+        push_nonvol_reg rbp\n+        alloc_stack     UM2MThunk_WrapperHelper_FIXED_STACK_ALLOC_SIZE\n+        set_frame       rbp, UM2MThunk_WrapperHelper_FRAME_OFFSET\n+        END_PROLOGUE\n+\n+        //\n+        // We are in cooperative mode and in the correct domain. \n+        // The host has also been notified that we've entered the \n+        // runtime.  All we have left to do is to copy the stack, \n+        // setup the register args and then call the managed target\n+        //\n+\n+        test            rdx, rdx\n+        jg              LOCAL_LABEL(UM2MThunk_WrapperHelper_CopyStackArgs)\n+\n+LOCAL_LABEL(UM2MThunk_WrapperHelper_ArgumentsSetup):\n+        mov             METHODDESC_REGISTER, r9\n+\n+        mov             r8, rdi                // rsi <- pThunkArgs\n+        mov             rdi, [r8 +  0h]\n+        mov             rsi, [r8 +  8h]\n+        mov             rdx, [r8 + 10h]\n+        mov             rcx, [r8 + 18h]\n+\n+        movdqa          xmm0, [r8 + UMThunkStubAMD64_XMM_SAVE_OFFSET - UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET +  0h]\n+        movdqa          xmm1, [r8 + UMThunkStubAMD64_XMM_SAVE_OFFSET - UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h]\n+        movdqa          xmm2, [r8 + UMThunkStubAMD64_XMM_SAVE_OFFSET - UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 20h]\n+        movdqa          xmm3, [r8 + UMThunkStubAMD64_XMM_SAVE_OFFSET - UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 30h]","path":"src/vm/amd64/umthunkstub.S","position":451,"original_position":451,"commit_id":"0ed7ada19451bd034641ca84e8be8a94b5ed59da","original_commit_id":"0ed7ada19451bd034641ca84e8be8a94b5ed59da","user":{"login":"sergiy-k","id":10781034,"avatar_url":"https://avatars.githubusercontent.com/u/10781034?v=3","gravatar_id":"","url":"https://api.github.com/users/sergiy-k","html_url":"https://github.com/sergiy-k","followers_url":"https://api.github.com/users/sergiy-k/followers","following_url":"https://api.github.com/users/sergiy-k/following{/other_user}","gists_url":"https://api.github.com/users/sergiy-k/gists{/gist_id}","starred_url":"https://api.github.com/users/sergiy-k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sergiy-k/subscriptions","organizations_url":"https://api.github.com/users/sergiy-k/orgs","repos_url":"https://api.github.com/users/sergiy-k/repos","events_url":"https://api.github.com/users/sergiy-k/events{/privacy}","received_events_url":"https://api.github.com/users/sergiy-k/received_events","type":"User","site_admin":false},"body":"same for xmm4-xmm7","created_at":"2015-02-24T08:39:43Z","updated_at":"2015-02-24T08:39:43Z","html_url":"https://github.com/dotnet/coreclr/pull/330#discussion_r25235778","pull_request_url":"https://api.github.com/repos/dotnet/coreclr/pulls/330","_links":{"self":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/comments/25235778"},"html":{"href":"https://github.com/dotnet/coreclr/pull/330#discussion_r25235778"},"pull_request":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/330"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/coreclr/pulls/330","id":29868772,"html_url":"https://github.com/dotnet/coreclr/pull/330","diff_url":"https://github.com/dotnet/coreclr/pull/330.diff","patch_url":"https://github.com/dotnet/coreclr/pull/330.patch","issue_url":"https://api.github.com/repos/dotnet/coreclr/issues/330","number":330,"state":"open","locked":false,"title":"Implement TheUMEntryPrestub, UMThunkStub, and UM2MThunk_WrapperHelper for UNIX ABIs","user":{"login":"kangaroo","id":151532,"avatar_url":"https://avatars.githubusercontent.com/u/151532?v=3","gravatar_id":"","url":"https://api.github.com/users/kangaroo","html_url":"https://github.com/kangaroo","followers_url":"https://api.github.com/users/kangaroo/followers","following_url":"https://api.github.com/users/kangaroo/following{/other_user}","gists_url":"https://api.github.com/users/kangaroo/gists{/gist_id}","starred_url":"https://api.github.com/users/kangaroo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kangaroo/subscriptions","organizations_url":"https://api.github.com/users/kangaroo/orgs","repos_url":"https://api.github.com/users/kangaroo/repos","events_url":"https://api.github.com/users/kangaroo/events{/privacy}","received_events_url":"https://api.github.com/users/kangaroo/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-02-24T03:38:54Z","updated_at":"2015-02-24T08:39:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"32b2d0c464f19cd0bb64a47569706da826eb46a4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/coreclr/pulls/330/commits","review_comments_url":"https://api.github.com/repos/dotnet/coreclr/pulls/330/comments","review_comment_url":"https://api.github.com/repos/dotnet/coreclr/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/coreclr/issues/330/comments","statuses_url":"https://api.github.com/repos/dotnet/coreclr/statuses/0ed7ada19451bd034641ca84e8be8a94b5ed59da","head":{"label":"kangaroo:issue-324","ref":"issue-324","sha":"0ed7ada19451bd034641ca84e8be8a94b5ed59da","user":{"login":"kangaroo","id":151532,"avatar_url":"https://avatars.githubusercontent.com/u/151532?v=3","gravatar_id":"","url":"https://api.github.com/users/kangaroo","html_url":"https://github.com/kangaroo","followers_url":"https://api.github.com/users/kangaroo/followers","following_url":"https://api.github.com/users/kangaroo/following{/other_user}","gists_url":"https://api.github.com/users/kangaroo/gists{/gist_id}","starred_url":"https://api.github.com/users/kangaroo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kangaroo/subscriptions","organizations_url":"https://api.github.com/users/kangaroo/orgs","repos_url":"https://api.github.com/users/kangaroo/repos","events_url":"https://api.github.com/users/kangaroo/events{/privacy}","received_events_url":"https://api.github.com/users/kangaroo/received_events","type":"User","site_admin":false},"repo":{"id":30268501,"name":"coreclr","full_name":"kangaroo/coreclr","owner":{"login":"kangaroo","id":151532,"avatar_url":"https://avatars.githubusercontent.com/u/151532?v=3","gravatar_id":"","url":"https://api.github.com/users/kangaroo","html_url":"https://github.com/kangaroo","followers_url":"https://api.github.com/users/kangaroo/followers","following_url":"https://api.github.com/users/kangaroo/following{/other_user}","gists_url":"https://api.github.com/users/kangaroo/gists{/gist_id}","starred_url":"https://api.github.com/users/kangaroo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kangaroo/subscriptions","organizations_url":"https://api.github.com/users/kangaroo/orgs","repos_url":"https://api.github.com/users/kangaroo/repos","events_url":"https://api.github.com/users/kangaroo/events{/privacy}","received_events_url":"https://api.github.com/users/kangaroo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kangaroo/coreclr","description":"This repo contains the .NET Core runtime, called CoreCLR. It is an execution engine for .NET apps, performing functions such as IL byte code loading, compilation to machine code and garbage collection. The repo contains the complete up-to-date CoreCLR codebase.","fork":true,"url":"https://api.github.com/repos/kangaroo/coreclr","forks_url":"https://api.github.com/repos/kangaroo/coreclr/forks","keys_url":"https://api.github.com/repos/kangaroo/coreclr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kangaroo/coreclr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kangaroo/coreclr/teams","hooks_url":"https://api.github.com/repos/kangaroo/coreclr/hooks","issue_events_url":"https://api.github.com/repos/kangaroo/coreclr/issues/events{/number}","events_url":"https://api.github.com/repos/kangaroo/coreclr/events","assignees_url":"https://api.github.com/repos/kangaroo/coreclr/assignees{/user}","branches_url":"https://api.github.com/repos/kangaroo/coreclr/branches{/branch}","tags_url":"https://api.github.com/repos/kangaroo/coreclr/tags","blobs_url":"https://api.github.com/repos/kangaroo/coreclr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kangaroo/coreclr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kangaroo/coreclr/git/refs{/sha}","trees_url":"https://api.github.com/repos/kangaroo/coreclr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kangaroo/coreclr/statuses/{sha}","languages_url":"https://api.github.com/repos/kangaroo/coreclr/languages","stargazers_url":"https://api.github.com/repos/kangaroo/coreclr/stargazers","contributors_url":"https://api.github.com/repos/kangaroo/coreclr/contributors","subscribers_url":"https://api.github.com/repos/kangaroo/coreclr/subscribers","subscription_url":"https://api.github.com/repos/kangaroo/coreclr/subscription","commits_url":"https://api.github.com/repos/kangaroo/coreclr/commits{/sha}","git_commits_url":"https://api.github.com/repos/kangaroo/coreclr/git/commits{/sha}","comments_url":"https://api.github.com/repos/kangaroo/coreclr/comments{/number}","issue_comment_url":"https://api.github.com/repos/kangaroo/coreclr/issues/comments{/number}","contents_url":"https://api.github.com/repos/kangaroo/coreclr/contents/{+path}","compare_url":"https://api.github.com/repos/kangaroo/coreclr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kangaroo/coreclr/merges","archive_url":"https://api.github.com/repos/kangaroo/coreclr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kangaroo/coreclr/downloads","issues_url":"https://api.github.com/repos/kangaroo/coreclr/issues{/number}","pulls_url":"https://api.github.com/repos/kangaroo/coreclr/pulls{/number}","milestones_url":"https://api.github.com/repos/kangaroo/coreclr/milestones{/number}","notifications_url":"https://api.github.com/repos/kangaroo/coreclr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kangaroo/coreclr/labels{/name}","releases_url":"https://api.github.com/repos/kangaroo/coreclr/releases{/id}","created_at":"2015-02-03T22:39:58Z","updated_at":"2015-02-17T23:51:58Z","pushed_at":"2015-02-24T04:07:02Z","git_url":"git://github.com/kangaroo/coreclr.git","ssh_url":"git@github.com:kangaroo/coreclr.git","clone_url":"https://github.com/kangaroo/coreclr.git","svn_url":"https://github.com/kangaroo/coreclr","homepage":"","size":26097,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"e3ab0d5f416d43878af0deb059dffc7aae5d2a02","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":30092893,"name":"coreclr","full_name":"dotnet/coreclr","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/coreclr","description":"This repo contains the .NET Core runtime, called CoreCLR. It is an execution engine for .NET apps, performing functions such as IL byte code loading, compilation to machine code and garbage collection. The repo contains the complete up-to-date CoreCLR codebase.","fork":false,"url":"https://api.github.com/repos/dotnet/coreclr","forks_url":"https://api.github.com/repos/dotnet/coreclr/forks","keys_url":"https://api.github.com/repos/dotnet/coreclr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/coreclr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/coreclr/teams","hooks_url":"https://api.github.com/repos/dotnet/coreclr/hooks","issue_events_url":"https://api.github.com/repos/dotnet/coreclr/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/coreclr/events","assignees_url":"https://api.github.com/repos/dotnet/coreclr/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/coreclr/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/coreclr/tags","blobs_url":"https://api.github.com/repos/dotnet/coreclr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/coreclr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/coreclr/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/coreclr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/coreclr/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/coreclr/languages","stargazers_url":"https://api.github.com/repos/dotnet/coreclr/stargazers","contributors_url":"https://api.github.com/repos/dotnet/coreclr/contributors","subscribers_url":"https://api.github.com/repos/dotnet/coreclr/subscribers","subscription_url":"https://api.github.com/repos/dotnet/coreclr/subscription","commits_url":"https://api.github.com/repos/dotnet/coreclr/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/coreclr/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/coreclr/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/coreclr/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/coreclr/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/coreclr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/coreclr/merges","archive_url":"https://api.github.com/repos/dotnet/coreclr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/coreclr/downloads","issues_url":"https://api.github.com/repos/dotnet/coreclr/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/coreclr/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/coreclr/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/coreclr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/coreclr/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/coreclr/releases{/id}","created_at":"2015-01-30T22:10:02Z","updated_at":"2015-02-24T08:38:37Z","pushed_at":"2015-02-24T01:19:57Z","git_url":"git://github.com/dotnet/coreclr.git","ssh_url":"git@github.com:dotnet/coreclr.git","clone_url":"https://github.com/dotnet/coreclr.git","svn_url":"https://github.com/dotnet/coreclr","homepage":"","size":30358,"stargazers_count":3670,"watchers_count":3670,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":578,"mirror_url":null,"open_issues_count":69,"forks":578,"open_issues":69,"watchers":3670,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/330"},"html":{"href":"https://github.com/dotnet/coreclr/pull/330"},"issue":{"href":"https://api.github.com/repos/dotnet/coreclr/issues/330"},"comments":{"href":"https://api.github.com/repos/dotnet/coreclr/issues/330/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/330/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/coreclr/pulls/330/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/coreclr/statuses/0ed7ada19451bd034641ca84e8be8a94b5ed59da"}}}}