Fixes issue #2643 and #2731
authorRahul Kumar <rahku@microsoft.com>
Mon, 29 Feb 2016 18:01:04 +0000 (10:01 -0800)
committerRahul Kumar <rahku@microsoft.com>
Mon, 29 Feb 2016 18:01:04 +0000 (10:01 -0800)
src/vm/arm64/asmconstants.h
src/vm/arm64/asmhelpers.asm
src/vm/arm64/gmscpu.h
src/vm/arm64/stubs.cpp

index 4ef204f..a574cc2 100644 (file)
@@ -76,18 +76,18 @@ ASMCONSTANTS_C_ASSERT(   CORINFO_NullReferenceException_ASM
 
 
 // Offset of the array containing the address of captured registers in MachState
-#define MachState__captureX19_X28 0x0
-ASMCONSTANTS_C_ASSERT(MachState__captureX19_X28 == offsetof(MachState, captureX19_X28))
+#define MachState__captureX19_X29 0x0
+ASMCONSTANTS_C_ASSERT(MachState__captureX19_X29 == offsetof(MachState, captureX19_X29))
 
 // Offset of the array containing the address of preserved registers in MachState
-#define MachState__ptrX19_X28 0x50
-ASMCONSTANTS_C_ASSERT(MachState__ptrX19_X28 == offsetof(MachState, ptrX19_X28))
+#define MachState__ptrX19_X29 0x58
+ASMCONSTANTS_C_ASSERT(MachState__ptrX19_X29 == offsetof(MachState, ptrX19_X29))
 
-#define MachState__isValid 0xb8
+#define MachState__isValid 0xc0
 ASMCONSTANTS_C_ASSERT(MachState__isValid == offsetof(MachState, _isValid))
 
-#define LazyMachState_captureX19_X28 MachState__captureX19_X28
-ASMCONSTANTS_C_ASSERT(LazyMachState_captureX19_X28 == offsetof(LazyMachState, captureX19_X28))
+#define LazyMachState_captureX19_X29 MachState__captureX19_X29
+ASMCONSTANTS_C_ASSERT(LazyMachState_captureX19_X29 == offsetof(LazyMachState, captureX19_X29))
 
 #define LazyMachState_captureSp     (MachState__isValid+8) // padding for alignment
 ASMCONSTANTS_C_ASSERT(LazyMachState_captureSp == offsetof(LazyMachState, captureSp))
@@ -95,9 +95,6 @@ ASMCONSTANTS_C_ASSERT(LazyMachState_captureSp == offsetof(LazyMachState, capture
 #define LazyMachState_captureIp     (LazyMachState_captureSp+8)
 ASMCONSTANTS_C_ASSERT(LazyMachState_captureIp == offsetof(LazyMachState, captureIp))
 
-#define LazyMachState_captureFp     (LazyMachState_captureSp+16)
-ASMCONSTANTS_C_ASSERT(LazyMachState_captureFp == offsetof(LazyMachState, captureFp))
-
 #define VASigCookie__pNDirectILStub 0x8
 ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub))
 
index 2965ced..5384f77 100644 (file)
 
         str     lr, [x0, #LazyMachState_captureIp]
 
-        str     fp, [x0, #LazyMachState_captureFp]
-
         ;; str instruction does not save sp register directly so move to temp register
         mov     x1, sp
         str     x1, [x0, #LazyMachState_captureSp]
 
         ;; save non-volatile registers that can contain object references
-        add     x1, x0, #LazyMachState_captureX19_X28
+        add     x1, x0, #LazyMachState_captureX19_X29
         stp     x19, x20, [x1, #(16*0)]
         stp     x21, x22, [x1, #(16*1)]
         stp     x23, x24, [x1, #(16*2)]
         stp     x25, x26, [x1, #(16*3)]
         stp     x27, x28, [x1, #(16*4)]
+        str     x29, [x1, #(16*5)]
 
         ret     lr
         LEAF_END
 
         ;
         ; If a preserved register were pushed onto the stack between
-        ; the managed caller and the H_M_F, ptrX19_X28 will point to its
+        ; the managed caller and the H_M_F, ptrX19_X29 will point to its
         ; location on the stack and it would have been updated on the
         ; stack by the GC already and it will be popped back into the
         ; appropriate register when the appropriate epilog is run.
@@ -93,7 +92,7 @@
         ; here because the GC will have updated our copies in the
         ; frame.
         ;
-        ; So, if ptrX19_X28 points into the MachState, we need to update
+        ; So, if ptrX19_X29 points into the MachState, we need to update
         ; the register here.  That's what this macro does.
         ;
 
         ;
         ; x0 = address of MachState
         ;
-        ; $regIndex: Index of the register (x19-x28). For x19, index is 19.
+        ; $regIndex: Index of the register (x19-x29). For x19, index is 19.
         ;            For x20, index is 20, and so on.
         ;
         ; $reg: Register name (e.g. x19, x20, etc)
         ;
         ; Get the address of the specified captured register from machine state
-        add     x2, x0, #(MachState__captureX19_X28 + (($regIndex-19)*8))
+        add     x2, x0, #(MachState__captureX19_X29 + (($regIndex-19)*8))
 
         ; Get the content of specified preserved register pointer from machine state
-        ldr     x3, [x0, #(MachState__ptrX19_X28 + (($regIndex-19)*8))]
+        ldr     x3, [x0, #(MachState__ptrX19_X29 + (($regIndex-19)*8))]
 
         cmp     x2, x3
         bne     %FT0
         RestoreRegMS 26, X26
         RestoreRegMS 27, X27
         RestoreRegMS 28, X28
+
 Done
         ; Its imperative that the return value of HelperMethodFrameRestoreState is zero
         ; as it is used in the state machine to loop until it becomes zero.
index 4607fca..eb813f8 100644 (file)
 
 #define __gmscpu_h__
 
-// X19 - X28
-#define NUM_NONVOLATILE_CONTEXT_POINTERS 10
+// X19 - X29
+#define NUM_NONVOLATILE_CONTEXT_POINTERS 11
 
 struct MachState {
-    ULONG64        captureX19_X28[NUM_NONVOLATILE_CONTEXT_POINTERS]; // preserved registers
-    PTR_ULONG64    ptrX19_X28[NUM_NONVOLATILE_CONTEXT_POINTERS]; // pointers to preserved registers
+    ULONG64        captureX19_X29[NUM_NONVOLATILE_CONTEXT_POINTERS]; // preserved registers
+    PTR_ULONG64    ptrX19_X29[NUM_NONVOLATILE_CONTEXT_POINTERS]; // pointers to preserved registers
     TADDR          _pc;
     TADDR          _sp;        
-    TADDR          _fp;
     BOOL           _isValid;
     
     BOOL   isValid()    { LIMITED_METHOD_DAC_CONTRACT; return _isValid; }
@@ -36,7 +35,6 @@ struct LazyMachState : public MachState{
 
     TADDR          captureSp;         // Stack pointer at the time of capture
     TADDR          captureIp;         // Instruction pointer at the time of capture
-    TADDR          captureFp;         // Frame pointer at the time of the captues
 
     void setLazyStateFromUnwind(MachState* copy);
     static void unwindLazyState(LazyMachState* baseState,
@@ -57,24 +55,23 @@ inline void LazyMachState::setLazyStateFromUnwind(MachState* copy)
 
     _sp = copy->_sp;
     _pc = copy->_pc;
-    _fp = copy->_fp;
 
     // Now copy the preserved register pointers. Note that some of the pointers could be
-    // pointing to copy->captureX19_X28[]. If that is case then while copying to destination
-    // ensure that they point to corresponding element in captureX19_X28[] of destination.
-    ULONG64* srcLowerBound = &copy->captureX19_X28[0];
-    ULONG64* srcUpperBound = (ULONG64*)((BYTE*)copy + offsetof(MachState, ptrX19_X28));
+    // pointing to copy->captureX19_X29[]. If that is case then while copying to destination
+    // ensure that they point to corresponding element in captureX19_X29[] of destination.
+    ULONG64* srcLowerBound = &copy->captureX19_X29[0];
+    ULONG64* srcUpperBound = (ULONG64*)((BYTE*)copy + offsetof(MachState, ptrX19_X29));
 
 
     for (int i = 0; i<NUM_NONVOLATILE_CONTEXT_POINTERS; i++)
     {
-        if (copy->ptrX19_X28[i] >= srcLowerBound && copy->ptrX19_X28[i] < srcUpperBound)
+        if (copy->ptrX19_X29[i] >= srcLowerBound && copy->ptrX19_X29[i] < srcUpperBound)
         {
-            ptrX19_X28[i] = (PTR_ULONG64)((BYTE*)copy->ptrX19_X28[i] - (BYTE*)srcLowerBound + (BYTE*)captureX19_X28);
+            ptrX19_X29[i] = (PTR_ULONG64)((BYTE*)copy->ptrX19_X29[i] - (BYTE*)srcLowerBound + (BYTE*)captureX19_X29);
         }
         else
         {
-            ptrX19_X28[i] = copy->ptrX19_X28[i];
+            ptrX19_X29[i] = copy->ptrX19_X29[i];
         }
     }
 
index de1f9e8..8125b1d 100644 (file)
@@ -277,39 +277,40 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
     T_CONTEXT context;
     T_KNONVOLATILE_CONTEXT_POINTERS nonVolContextPtrs;
 
-    context.X19 = unwoundstate->captureX19_X28[0] = baseState->captureX19_X28[0];
-    context.X20 = unwoundstate->captureX19_X28[1] = baseState->captureX19_X28[1];
-    context.X21 = unwoundstate->captureX19_X28[2] = baseState->captureX19_X28[2];
-    context.X22 = unwoundstate->captureX19_X28[3] = baseState->captureX19_X28[3];
-    context.X23 = unwoundstate->captureX19_X28[4] = baseState->captureX19_X28[4];
-    context.X24 = unwoundstate->captureX19_X28[5] = baseState->captureX19_X28[5];
-    context.X25 = unwoundstate->captureX19_X28[6] = baseState->captureX19_X28[6];
-    context.X26 = unwoundstate->captureX19_X28[7] = baseState->captureX19_X28[7];
-    context.X27 = unwoundstate->captureX19_X28[8] = baseState->captureX19_X28[8];
-    context.X28 = unwoundstate->captureX19_X28[9] = baseState->captureX19_X28[9];
+    context.X19 = unwoundstate->captureX19_X29[0] = baseState->captureX19_X29[0];
+    context.X20 = unwoundstate->captureX19_X29[1] = baseState->captureX19_X29[1];
+    context.X21 = unwoundstate->captureX19_X29[2] = baseState->captureX19_X29[2];
+    context.X22 = unwoundstate->captureX19_X29[3] = baseState->captureX19_X29[3];
+    context.X23 = unwoundstate->captureX19_X29[4] = baseState->captureX19_X29[4];
+    context.X24 = unwoundstate->captureX19_X29[5] = baseState->captureX19_X29[5];
+    context.X25 = unwoundstate->captureX19_X29[6] = baseState->captureX19_X29[6];
+    context.X26 = unwoundstate->captureX19_X29[7] = baseState->captureX19_X29[7];
+    context.X27 = unwoundstate->captureX19_X29[8] = baseState->captureX19_X29[8];
+    context.X28 = unwoundstate->captureX19_X29[9] = baseState->captureX19_X29[9];
+    context.Fp  = unwoundstate->captureX19_X29[10] = baseState->captureX19_X29[10];    
 
     context.Sp = baseState->captureSp;
     context.Pc = baseState->captureIp;
-    context.Fp = baseState->captureFp;
 
 #if !defined(DACCESS_COMPILE)
     // For DAC, if we get here, it means that the LazyMachState is uninitialized and we have to unwind it.
     // The API we use to unwind in DAC is StackWalk64(), which does not support the context pointers.
     //
     // Restore the integer registers to KNONVOLATILE_CONTEXT_POINTERS to be used for unwinding.
-    nonVolContextPtrs.X19 = &unwoundstate->captureX19_X28[0];
-    nonVolContextPtrs.X20 = &unwoundstate->captureX19_X28[1];
-    nonVolContextPtrs.X21 = &unwoundstate->captureX19_X28[2];
-    nonVolContextPtrs.X22 = &unwoundstate->captureX19_X28[3];
-    nonVolContextPtrs.X23 = &unwoundstate->captureX19_X28[4];
-    nonVolContextPtrs.X24 = &unwoundstate->captureX19_X28[5];
-    nonVolContextPtrs.X25 = &unwoundstate->captureX19_X28[6];
-    nonVolContextPtrs.X26 = &unwoundstate->captureX19_X28[7];
-    nonVolContextPtrs.X27 = &unwoundstate->captureX19_X28[8];
-    nonVolContextPtrs.X28 = &unwoundstate->captureX19_X28[9];
+    nonVolContextPtrs.X19 = &unwoundstate->captureX19_X29[0];
+    nonVolContextPtrs.X20 = &unwoundstate->captureX19_X29[1];
+    nonVolContextPtrs.X21 = &unwoundstate->captureX19_X29[2];
+    nonVolContextPtrs.X22 = &unwoundstate->captureX19_X29[3];
+    nonVolContextPtrs.X23 = &unwoundstate->captureX19_X29[4];
+    nonVolContextPtrs.X24 = &unwoundstate->captureX19_X29[5];
+    nonVolContextPtrs.X25 = &unwoundstate->captureX19_X29[6];
+    nonVolContextPtrs.X26 = &unwoundstate->captureX19_X29[7];
+    nonVolContextPtrs.X27 = &unwoundstate->captureX19_X29[8];
+    nonVolContextPtrs.X28 = &unwoundstate->captureX19_X29[9];
+    nonVolContextPtrs.Fp  = &unwoundstate->captureX19_X29[10]; 
 #endif // DACCESS_COMPILE
 
-    LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK    LazyMachState::unwindLazyState(ip:%p,sp:%p,fp:%p)\n", baseState->captureIp, baseState->captureSp, baseState->captureFp));
+    LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK    LazyMachState::unwindLazyState(ip:%p,sp:%p)\n", baseState->captureIp, baseState->captureSp));
 
     PCODE pvControlPc;
 
@@ -355,33 +356,34 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
 
 #ifdef DACCESS_COMPILE
     // For DAC builds, we update the registers directly since we dont have context pointers
-    unwoundstate->captureX19_X28[0] = context.X19;
-    unwoundstate->captureX19_X28[1] = context.X20;
-    unwoundstate->captureX19_X28[2] = context.X21;
-    unwoundstate->captureX19_X28[3] = context.X22;
-    unwoundstate->captureX19_X28[4] = context.X23;
-    unwoundstate->captureX19_X28[5] = context.X24;
-    unwoundstate->captureX19_X28[6] = context.X25;
-    unwoundstate->captureX19_X28[7] = context.X26;
-    unwoundstate->captureX19_X28[8] = context.X27;
-    unwoundstate->captureX19_X28[9] = context.X28;
+    unwoundstate->captureX19_X29[0] = context.X19;
+    unwoundstate->captureX19_X29[1] = context.X20;
+    unwoundstate->captureX19_X29[2] = context.X21;
+    unwoundstate->captureX19_X29[3] = context.X22;
+    unwoundstate->captureX19_X29[4] = context.X23;
+    unwoundstate->captureX19_X29[5] = context.X24;
+    unwoundstate->captureX19_X29[6] = context.X25;
+    unwoundstate->captureX19_X29[7] = context.X26;
+    unwoundstate->captureX19_X29[8] = context.X27;
+    unwoundstate->captureX19_X29[9] = context.X28;
+    unwoundstate->captureX19_X29[10] = context.Fp;     
 #else // !DACCESS_COMPILE
     // For non-DAC builds, update the register state from context pointers
-    unwoundstate->ptrX19_X28[0] = nonVolContextPtrs.X19;
-    unwoundstate->ptrX19_X28[1] = nonVolContextPtrs.X20;
-    unwoundstate->ptrX19_X28[2] = nonVolContextPtrs.X21;
-    unwoundstate->ptrX19_X28[3] = nonVolContextPtrs.X22;
-    unwoundstate->ptrX19_X28[4] = nonVolContextPtrs.X23;
-    unwoundstate->ptrX19_X28[5] = nonVolContextPtrs.X24;
-    unwoundstate->ptrX19_X28[6] = nonVolContextPtrs.X25;
-    unwoundstate->ptrX19_X28[7] = nonVolContextPtrs.X26;
-    unwoundstate->ptrX19_X28[8] = nonVolContextPtrs.X27;
-    unwoundstate->ptrX19_X28[9] = nonVolContextPtrs.X28;
+    unwoundstate->ptrX19_X29[0] = nonVolContextPtrs.X19;
+    unwoundstate->ptrX19_X29[1] = nonVolContextPtrs.X20;
+    unwoundstate->ptrX19_X29[2] = nonVolContextPtrs.X21;
+    unwoundstate->ptrX19_X29[3] = nonVolContextPtrs.X22;
+    unwoundstate->ptrX19_X29[4] = nonVolContextPtrs.X23;
+    unwoundstate->ptrX19_X29[5] = nonVolContextPtrs.X24;
+    unwoundstate->ptrX19_X29[6] = nonVolContextPtrs.X25;
+    unwoundstate->ptrX19_X29[7] = nonVolContextPtrs.X26;
+    unwoundstate->ptrX19_X29[8] = nonVolContextPtrs.X27;
+    unwoundstate->ptrX19_X29[9] = nonVolContextPtrs.X28;
+    unwoundstate->ptrX19_X29[10] = nonVolContextPtrs.Fp;       
 #endif // DACCESS_COMPILE
 
     unwoundstate->_pc = context.Pc;
     unwoundstate->_sp = context.Sp;
-    unwoundstate->_fp = context.Fp;
 
     unwoundstate->_isValid = TRUE;
 }
@@ -418,18 +420,18 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
 
         pRD->pCurrentContext->Pc = pRD->ControlPC = pUnwoundState->_pc;
         pRD->pCurrentContext->Sp = pRD->SP        = pUnwoundState->_sp;
-        pRD->pCurrentContext->Fp = pUnwoundState->_fp;
-
-        pRD->pCurrentContext->X19 = (DWORD64)(pUnwoundState->captureX19_X28[0]);
-        pRD->pCurrentContext->X20 = (DWORD64)(pUnwoundState->captureX19_X28[1]);
-        pRD->pCurrentContext->X21 = (DWORD64)(pUnwoundState->captureX19_X28[2]);
-        pRD->pCurrentContext->X22 = (DWORD64)(pUnwoundState->captureX19_X28[3]);
-        pRD->pCurrentContext->X23 = (DWORD64)(pUnwoundState->captureX19_X28[4]);
-        pRD->pCurrentContext->X24 = (DWORD64)(pUnwoundState->captureX19_X28[5]);
-        pRD->pCurrentContext->X25 = (DWORD64)(pUnwoundState->captureX19_X28[6]);
-        pRD->pCurrentContext->X26 = (DWORD64)(pUnwoundState->captureX19_X28[7]);
-        pRD->pCurrentContext->X27 = (DWORD64)(pUnwoundState->captureX19_X28[8]);
-        pRD->pCurrentContext->X28 = (DWORD64)(pUnwoundState->captureX19_X28[9]);
+
+        pRD->pCurrentContext->X19 = (DWORD64)(pUnwoundState->captureX19_X29[0]);
+        pRD->pCurrentContext->X20 = (DWORD64)(pUnwoundState->captureX19_X29[1]);
+        pRD->pCurrentContext->X21 = (DWORD64)(pUnwoundState->captureX19_X29[2]);
+        pRD->pCurrentContext->X22 = (DWORD64)(pUnwoundState->captureX19_X29[3]);
+        pRD->pCurrentContext->X23 = (DWORD64)(pUnwoundState->captureX19_X29[4]);
+        pRD->pCurrentContext->X24 = (DWORD64)(pUnwoundState->captureX19_X29[5]);
+        pRD->pCurrentContext->X25 = (DWORD64)(pUnwoundState->captureX19_X29[6]);
+        pRD->pCurrentContext->X26 = (DWORD64)(pUnwoundState->captureX19_X29[7]);
+        pRD->pCurrentContext->X27 = (DWORD64)(pUnwoundState->captureX19_X29[8]);
+        pRD->pCurrentContext->X28 = (DWORD64)(pUnwoundState->captureX19_X29[9]);
+        pRD->pCurrentContext->Fp = (DWORD64)(pUnwoundState->captureX19_X29[10]);
 
         return;
     }
@@ -442,30 +444,31 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
     
     pRD->pCurrentContext->Pc = pRD->ControlPC;
     pRD->pCurrentContext->Sp = pRD->SP;
-    pRD->pCurrentContext->Fp = (DWORD64)(size_t)m_MachState._fp;
-
-    pRD->pCurrentContext->X19 = *m_MachState.ptrX19_X28[0];
-    pRD->pCurrentContext->X20 = *m_MachState.ptrX19_X28[1];
-    pRD->pCurrentContext->X21 = *m_MachState.ptrX19_X28[2];
-    pRD->pCurrentContext->X22 = *m_MachState.ptrX19_X28[3];
-    pRD->pCurrentContext->X23 = *m_MachState.ptrX19_X28[4];
-    pRD->pCurrentContext->X24 = *m_MachState.ptrX19_X28[5];
-    pRD->pCurrentContext->X25 = *m_MachState.ptrX19_X28[6];
-    pRD->pCurrentContext->X26 = *m_MachState.ptrX19_X28[7];
-    pRD->pCurrentContext->X27 = *m_MachState.ptrX19_X28[8];
-    pRD->pCurrentContext->X28 = *m_MachState.ptrX19_X28[9];
+
+    pRD->pCurrentContext->X19 = *m_MachState.ptrX19_X29[0];
+    pRD->pCurrentContext->X20 = *m_MachState.ptrX19_X29[1];
+    pRD->pCurrentContext->X21 = *m_MachState.ptrX19_X29[2];
+    pRD->pCurrentContext->X22 = *m_MachState.ptrX19_X29[3];
+    pRD->pCurrentContext->X23 = *m_MachState.ptrX19_X29[4];
+    pRD->pCurrentContext->X24 = *m_MachState.ptrX19_X29[5];
+    pRD->pCurrentContext->X25 = *m_MachState.ptrX19_X29[6];
+    pRD->pCurrentContext->X26 = *m_MachState.ptrX19_X29[7];
+    pRD->pCurrentContext->X27 = *m_MachState.ptrX19_X29[8];
+    pRD->pCurrentContext->X28 = *m_MachState.ptrX19_X29[9];
+    pRD->pCurrentContext->Fp  = *m_MachState.ptrX19_X29[10];
 
 #if !defined(DACCESS_COMPILE)    
-    pRD->pCurrentContextPointers->X19 = m_MachState.ptrX19_X28[0];
-    pRD->pCurrentContextPointers->X20 = m_MachState.ptrX19_X28[1];
-    pRD->pCurrentContextPointers->X21 = m_MachState.ptrX19_X28[2];
-    pRD->pCurrentContextPointers->X22 = m_MachState.ptrX19_X28[3];
-    pRD->pCurrentContextPointers->X23 = m_MachState.ptrX19_X28[4];
-    pRD->pCurrentContextPointers->X24 = m_MachState.ptrX19_X28[5];
-    pRD->pCurrentContextPointers->X25 = m_MachState.ptrX19_X28[6];
-    pRD->pCurrentContextPointers->X26 = m_MachState.ptrX19_X28[7];
-    pRD->pCurrentContextPointers->X27 = m_MachState.ptrX19_X28[8];
-    pRD->pCurrentContextPointers->X28 = m_MachState.ptrX19_X28[9];
+    pRD->pCurrentContextPointers->X19 = m_MachState.ptrX19_X29[0];
+    pRD->pCurrentContextPointers->X20 = m_MachState.ptrX19_X29[1];
+    pRD->pCurrentContextPointers->X21 = m_MachState.ptrX19_X29[2];
+    pRD->pCurrentContextPointers->X22 = m_MachState.ptrX19_X29[3];
+    pRD->pCurrentContextPointers->X23 = m_MachState.ptrX19_X29[4];
+    pRD->pCurrentContextPointers->X24 = m_MachState.ptrX19_X29[5];
+    pRD->pCurrentContextPointers->X25 = m_MachState.ptrX19_X29[6];
+    pRD->pCurrentContextPointers->X26 = m_MachState.ptrX19_X29[7];
+    pRD->pCurrentContextPointers->X27 = m_MachState.ptrX19_X29[8];
+    pRD->pCurrentContextPointers->X28 = m_MachState.ptrX19_X29[9];
+    pRD->pCurrentContextPointers->Fp = m_MachState.ptrX19_X29[10];
     pRD->pCurrentContextPointers->Lr = NULL;
 #endif
 }