Revert "Revert "Merge branch 'master' of https://github.com/mono/mono""
[mono.git] / mono / utils / mono-context.c
index ecf9a488b0cd61cfb91f60ccde42c88c80fbcebb..bc0286485fc008a9d5d7cdf3ba8e2dde36e92a80 100644 (file)
@@ -245,12 +245,15 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
 
 #include <mono/utils/mono-context.h>
 #include <mono/arch/arm/arm-codegen.h>
+#include <mono/arch/arm/arm-vfp-codegen.h>
 
 void
 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 {
 #ifdef MONO_CROSS_COMPILE
        g_assert_not_reached ();
+#elif defined(__native_client__)
+       g_assert_not_reached ();
 #else
        arm_ucontext *my_uc = sigctx;
 
@@ -258,6 +261,9 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc);
        mctx->cpsr = UCONTEXT_REG_CPSR (my_uc);
        memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16);
+#ifdef UCONTEXT_REG_VFPREGS
+       memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16);
+#endif
 #endif
 }
 
@@ -266,15 +272,81 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
 {
 #ifdef MONO_CROSS_COMPILE
        g_assert_not_reached ();
+#elif defined(__native_client__)
+       g_assert_not_reached ();
 #else
        arm_ucontext *my_uc = ctx;
 
        UCONTEXT_REG_PC (my_uc) = mctx->pc;
-       UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_FP];
+       UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_SP];
        UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr;
        /* The upper registers are not guaranteed to be valid */
        memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12);
+#ifdef UCONTEXT_REG_VFPREGS
+       memcpy (UCONTEXT_REG_VFPREGS (my_uc), &mctx->fregs, sizeof (double) * 16);
+#endif
+#endif
+}
+
+#elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
+
+#include <mono/utils/mono-context.h>
+
+void
+mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
+{
+#ifdef MONO_CROSS_COMPILE
+       g_assert_not_reached ();
+#else
+       memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
+       mctx->pc = UCONTEXT_REG_PC (sigctx);
+       mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
+       /*
+        * We don't handle fp regs, this is not currrently a
+        * problem, since we don't allocate them globally.
+        */
+#endif
+}
+
+void
+mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
+{
+#ifdef MONO_CROSS_COMPILE
+       g_assert_not_reached ();
+#else
+       memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
+       UCONTEXT_REG_PC (sigctx) = mctx->pc;
+       UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
 #endif
 }
 
+#elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
+
+#include <mono/utils/mono-context.h>
+#include <mono/arch/mips/mips-codegen.h>
+
+void
+mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
+{
+       int i;
+
+       mctx->sc_pc = UCONTEXT_REG_PC (sigctx);
+       for (i = 0; i < 32; ++i) {
+               mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i];
+               mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i];
+       }
+}
+
+void
+mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
+{
+       int i;
+
+       UCONTEXT_REG_PC (sigctx) = mctx->sc_pc;
+       for (i = 0; i < 32; ++i) {
+               UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i];
+               UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i];
+       }
+}
+
 #endif /* #if defined(__i386__) */