[runtime] Use the windows CONTEXT<->MonoContext conversion code to mono-context.c...
[mono.git] / mono / utils / mono-context.h
index 84409cf1e77d9b0e3dc31d24a0862d342737bd46..251e58111d1ec96c883f7d42f3045bb901a65f40 100755 (executable)
@@ -118,7 +118,8 @@ typedef struct {
         __asm mov [eax+0x14], esp                                                                                      \
         __asm mov [eax+0x18], esi                                                                                      \
         __asm mov [eax+0x1c], edi                                                                                      \
-        __asm call $+5                                                                                                         \
+        __asm call __mono_context_get_ip                                                                       \
+        __asm __mono_context_get_ip:                                                                           \
         __asm pop dword ptr [eax+0x20]                                                                         \
                 }                                                                                                                              \
        } while (0)
@@ -179,7 +180,12 @@ typedef struct {
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->rbp))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->rsp))
 
-#if defined(__native_client__)
+#if defined (HOST_WIN32) && !defined(__GNUC__)
+/* msvc doesn't support inline assembly, so have to use a separate .asm file */
+extern void mono_context_get_current (void *);
+#define MONO_CONTEXT_GET_CURRENT(ctx) do { mono_context_get_current((void*)&(ctx)); } while (0)
+
+#elif defined(__native_client__)
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
                "movq $0x0,  %%nacl:0x00(%%r15, %0, 1)\n"       \
@@ -222,16 +228,15 @@ typedef struct {
                "movq %%r13, 0x68(%0)\n"        \
                "movq %%r14, 0x70(%0)\n"        \
                "movq %%r15, 0x78(%0)\n"        \
-               "leaq (%%rip), %%rdx\n" \
+               /* "leaq (%%rip), %%rdx\n" is not understood by icc */  \
+               ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
                "movq %%rdx, 0x80(%0)\n"        \
                :       \
                : "a" (&(ctx))  \
                : "rdx", "memory")
 #endif
 
-#if !defined(HOST_WIN32)
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
-#endif
 
 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM)) /* defined(__x86_64__) */
 
@@ -274,6 +279,57 @@ typedef struct {
        ctx.pc = ctx.regs [15];                 \
 } while (0)
 
+#elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
+
+#include <mono/arch/arm64/arm64-codegen.h>
+
+typedef struct {
+       mgreg_t regs [32];
+       double fregs [32];
+       mgreg_t pc;
+} MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->pc = (mgreg_t)ip; } while (0)
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->regs [ARMREG_FP] = (mgreg_t)bp; } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,bp) do { (ctx)->regs [ARMREG_SP] = (mgreg_t)bp; } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) (gpointer)((ctx)->pc)
+#define MONO_CONTEXT_GET_BP(ctx) (gpointer)((ctx)->regs [ARMREG_FP])
+#define MONO_CONTEXT_GET_SP(ctx) (gpointer)((ctx)->regs [ARMREG_SP])
+
+#define MONO_CONTEXT_GET_CURRENT(ctx)  do {    \
+       __asm__ __volatile__(                   \
+               "mov x16, %0\n" \
+               "stp x0, x1, [x16], #16\n"      \
+               "stp x2, x3, [x16], #16\n"      \
+               "stp x4, x5, [x16], #16\n"      \
+               "stp x6, x7, [x16], #16\n"      \
+               "stp x8, x9, [x16], #16\n"      \
+               "stp x10, x11, [x16], #16\n"    \
+               "stp x12, x13, [x16], #16\n"    \
+               "stp x14, x15, [x16], #16\n"    \
+               "stp xzr, x17, [x16], #16\n"    \
+               "stp x18, x19, [x16], #16\n"    \
+               "stp x20, x21, [x16], #16\n"    \
+               "stp x22, x23, [x16], #16\n"    \
+               "stp x24, x25, [x16], #16\n"    \
+               "stp x26, x27, [x16], #16\n"    \
+               "stp x28, x29, [x16], #16\n"    \
+               "stp x30, xzr, [x16]\n" \
+               "mov x30, sp\n"                         \
+               "str x30, [x16, #8]\n"          \
+               :                                                       \
+               : "r" (&ctx.regs)                       \
+               : "x30", "memory"                       \
+       );                                                              \
+       __asm__ __volatile__( \
+               "adr %0, L0\n" \
+               "L0:\n" \
+               : "=r" (ctx.pc)         \
+               :                                       \
+               : "memory"                       \
+       ); \
+} while (0)
 
 #elif defined(__mono_ppc__) /* defined(__arm__) */
 
@@ -488,7 +544,18 @@ typedef struct ucontext MonoContext;
 
 #endif
 
+/*
+ * The naming is misleading, the SIGCTX argument should be the platform's context
+ * structure (ucontext_c on posix, CONTEXT on windows).
+ */
 void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) MONO_INTERNAL;
+
+/*
+ * This will not completely initialize SIGCTX since MonoContext contains less
+ * information that the system context. The caller should obtain a SIGCTX from
+ * the system, and use this function to override the parts of it which are
+ * also in MonoContext.
+ */
 void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) MONO_INTERNAL;
 
 #endif /* __MONO_MONO_CONTEXT_H__ */