1 | // Licensed to the .NET Foundation under one or more agreements. |
---|---|
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // =========================================================================== |
5 | // File: JITHelpers.CPP |
6 | // =========================================================================== |
7 | |
8 | // This contains JITinterface routines that are specific to the |
9 | // AMD64 platform. They are modeled after the X86 specific routines |
10 | // found in JIThelp.asm |
11 | |
12 | |
13 | #include "common.h" |
14 | #include "jitinterface.h" |
15 | #include "eeconfig.h" |
16 | #include "excep.h" |
17 | #include "ecall.h" |
18 | #include "asmconstants.h" |
19 | |
20 | EXTERN_C void JIT_TailCallHelperStub_ReturnAddress(); |
21 | |
22 | TailCallFrame * TailCallFrame::GetFrameFromContext(CONTEXT * pContext) |
23 | { |
24 | _ASSERTE((void*)::GetIP(pContext) == JIT_TailCallHelperStub_ReturnAddress); |
25 | return (TailCallFrame*)(pContext->R13 + sizeof(GSCookie)); |
26 | } |
27 | |
28 | // Assuming pContext is a plain generic call-site, adjust it to look like |
29 | // it called into TailCallHelperStub, and is at the point of the call. |
30 | TailCallFrame * TailCallFrame::AdjustContextForTailCallHelperStub(CONTEXT * pContext, size_t cbNewArgArea, Thread * pThread) |
31 | { |
32 | TailCallFrame * pNewFrame = (TailCallFrame *)(GetSP(pContext) - sizeof(TailCallFrame)); |
33 | |
34 | // R13 is the frame pointer (for popping the stack) |
35 | pContext->R13 = (size_t)pNewFrame - sizeof(GSCookie); |
36 | // R12 is the previous stack pointer, so we can determine if a return buffer from the |
37 | // immediate caller (and thus being discarded via the tail call), or someplace else |
38 | pContext->R12 = GetSP(pContext); |
39 | // for the args and pushed return address of the 'call' |
40 | SetSP(pContext, (size_t)pNewFrame - (cbNewArgArea + sizeof(void*) + sizeof(GSCookie))); |
41 | |
42 | // For popping the Frame, store the Thread |
43 | pContext->R14 = (DWORD_PTR)pThread; |
44 | // And the current head/top |
45 | pContext->R15 = (DWORD_PTR)pThread->GetFrame(); // m_Next |
46 | |
47 | return (TailCallFrame *) pNewFrame; |
48 | } |
49 |