Revert "Revert "Merge branch 'master' of https://github.com/mono/mono""
[mono.git] / mono / utils / mono-context.h
old mode 100644 (file)
new mode 100755 (executable)
index edc91c6..a4d2946
@@ -25,7 +25,7 @@
  * MONO_CONTEXT_GET_CURRENT captures the current context as close as possible. One reg might be clobbered
  *  to hold the address of the target MonoContext. It will be a caller save one, so should not be a problem.
  */
-#if defined(__i386__)
+#if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
 
 /*HACK, move this to an eventual mono-signal.c*/
 #if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \
@@ -105,6 +105,24 @@ typedef struct {
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->esp))
 
 /*We set EAX to zero since we are clobering it anyway*/
+#ifdef _MSC_VER
+#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
+       void *_ptr = &(ctx);                                                                                            \
+       __asm {                                                                                                                         \
+        __asm mov eax, _ptr                                                                                            \
+        __asm mov [eax+0x00], eax                                                                                      \
+        __asm mov [eax+0x04], ebx                                                                                      \
+        __asm mov [eax+0x08], ecx                                                                                      \
+        __asm mov [eax+0x0c], edx                                                                                      \
+        __asm mov [eax+0x10], ebp                                                                                      \
+        __asm mov [eax+0x14], esp                                                                                      \
+        __asm mov [eax+0x18], esi                                                                                      \
+        __asm mov [eax+0x1c], edi                                                                                      \
+        __asm call $+5                                                                                                         \
+        __asm pop dword ptr [eax+0x20]                                                                         \
+                }                                                                                                                              \
+       } while (0)
+#else
 #define MONO_CONTEXT_GET_CURRENT(ctx) \
        __asm__ __volatile__(   \
        "movl $0x0, 0x00(%0)\n" \
@@ -120,10 +138,11 @@ typedef struct {
        :       \
        : "a" (&(ctx))  \
        : "memory")
+#endif
 
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
 
-#elif defined(__x86_64__) /* defined(__i386__) */
+#elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
 
 
 #if !defined( HOST_WIN32 ) && !defined(__native_client__) && !defined(__native_client_codegen__)
@@ -160,6 +179,31 @@ typedef struct {
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->rbp))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->rsp))
 
+#if defined(__native_client__)
+#define MONO_CONTEXT_GET_CURRENT(ctx)  \
+       __asm__ __volatile__(   \
+               "movq $0x0,  %%nacl:0x00(%%r15, %0, 1)\n"       \
+               "movq %%rbx, %%nacl:0x08(%%r15, %0, 1)\n"       \
+               "movq %%rcx, %%nacl:0x10(%%r15, %0, 1)\n"       \
+               "movq %%rdx, %%nacl:0x18(%%r15, %0, 1)\n"       \
+               "movq %%rbp, %%nacl:0x20(%%r15, %0, 1)\n"       \
+               "movq %%rsp, %%nacl:0x28(%%r15, %0, 1)\n"       \
+               "movq %%rsi, %%nacl:0x30(%%r15, %0, 1)\n"       \
+               "movq %%rdi, %%nacl:0x38(%%r15, %0, 1)\n"       \
+               "movq %%r8,  %%nacl:0x40(%%r15, %0, 1)\n"       \
+               "movq %%r9,  %%nacl:0x48(%%r15, %0, 1)\n"       \
+               "movq %%r10, %%nacl:0x50(%%r15, %0, 1)\n"       \
+               "movq %%r11, %%nacl:0x58(%%r15, %0, 1)\n"       \
+               "movq %%r12, %%nacl:0x60(%%r15, %0, 1)\n"       \
+               "movq %%r13, %%nacl:0x68(%%r15, %0, 1)\n"       \
+               "movq %%r14, %%nacl:0x70(%%r15, %0, 1)\n"       \
+               "movq %%r15, %%nacl:0x78(%%r15, %0, 1)\n"       \
+               "leaq (%%rip), %%rdx\n" \
+               "movq %%rdx, %%nacl:0x80(%%r15, %0, 1)\n"       \
+               :       \
+               : "a" ((int64_t)&(ctx)) \
+               : "rdx", "memory")
+#else
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
                "movq $0x0,  0x00(%0)\n"        \
@@ -183,30 +227,103 @@ typedef struct {
                :       \
                : "a" (&(ctx))  \
                : "rdx", "memory")
+#endif
 
+#if !defined(HOST_WIN32)
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
+#endif
 
-#elif defined(__arm__) /* defined(__x86_64__) */
+#elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM)) /* defined(__x86_64__) */
 
 typedef struct {
-       gulong eip;          // pc 
-       gulong esp;          // sp
-       gulong regs [16];
-       double fregs [8];
+       mgreg_t pc;
+       mgreg_t regs [16];
+       double fregs [16];
+       mgreg_t cpsr;
 } MonoContext;
 
 /* we have the stack pointer, not the base pointer in sigcontext */
-#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (int)ip; } while (0); 
-#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->regs [ARMREG_FP] = (int)bp; } while (0); 
-#define MONO_CONTEXT_SET_SP(ctx,bp) do { (ctx)->esp = (int)bp; } while (0); 
+#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)->eip))
+#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)->esp))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->regs [ARMREG_SP]))
 
-// FIXME:
 #define MONO_CONTEXT_GET_CURRENT(ctx)  do {    \
-       g_assert_not_reached (); \
+       __asm__ __volatile__(                   \
+               "push {r0}\n"                           \
+               "push {r1}\n"                           \
+               "mov r0, %0\n"                          \
+               "ldr r1, [sp, #4]\n"                    \
+               "str r1, [r0]!\n"                       \
+               "ldr r1, [sp, #0]\n"                    \
+               "str r1, [r0]!\n"                       \
+               "stmia r0!, {r2-r12}\n"         \
+               "str sp, [r0]!\n"                       \
+               "str lr, [r0]!\n"                       \
+               "mov r1, pc\n"                          \
+               "str r1, [r0]!\n"                       \
+               "pop {r1}\n"                            \
+               "pop {r0}\n"                            \
+               :                                                       \
+               : "r" (&ctx.regs)                       \
+               : "memory"                                      \
+       );                                                              \
+       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__) */
@@ -332,29 +449,60 @@ mono_ia64_context_get_fp (MonoContext *ctx)
        return fp;
 }
 
-#elif defined(__mips__) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */
+#elif ((defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */
 
-/* we define our own structure and we'll copy the data
- * from sigcontext/ucontext/mach when we need it.
- * This also makes us save stack space and time when copying
- * We might also want to add an additional field to propagate
- * the original context from the signal handler.
- */
 typedef struct {
-       gpointer        sc_pc;
-       guint32         sc_regs [32];
+       mgreg_t     sc_pc;
+       mgreg_t         sc_regs [32];
        gfloat          sc_fpregs [32];
 } MonoContext;
 
-/* we have the stack pointer, not the base pointer in sigcontext */
-#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (int)(ip); } while (0);
-#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (int)(bp); } while (0);
-#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (int)(sp); } while (0);
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (mgreg_t)(ip); } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (mgreg_t)(bp); } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (mgreg_t)(sp); } while (0);
 
 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_pc))
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->sc_regs[mips_fp]))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_regs[mips_sp]))
 
+#define MONO_CONTEXT_GET_CURRENT(ctx)  \
+       __asm__ __volatile__(   \
+               "sw $0,0(%0)\n\t"       \
+               "sw $1,4(%0)\n\t"       \
+               "sw $2,8(%0)\n\t"       \
+               "sw $3,12(%0)\n\t"      \
+               "sw $4,16(%0)\n\t"      \
+               "sw $5,20(%0)\n\t"      \
+               "sw $6,24(%0)\n\t"      \
+               "sw $7,28(%0)\n\t"      \
+               "sw $8,32(%0)\n\t"      \
+               "sw $9,36(%0)\n\t"      \
+               "sw $10,40(%0)\n\t"     \
+               "sw $11,44(%0)\n\t"     \
+               "sw $12,48(%0)\n\t"     \
+               "sw $13,52(%0)\n\t"     \
+               "sw $14,56(%0)\n\t"     \
+               "sw $15,60(%0)\n\t"     \
+               "sw $16,64(%0)\n\t"     \
+               "sw $17,68(%0)\n\t"     \
+               "sw $18,72(%0)\n\t"     \
+               "sw $19,76(%0)\n\t"     \
+               "sw $20,80(%0)\n\t"     \
+               "sw $21,84(%0)\n\t"     \
+               "sw $22,88(%0)\n\t"     \
+               "sw $23,92(%0)\n\t"     \
+               "sw $24,96(%0)\n\t"     \
+               "sw $25,100(%0)\n\t"    \
+               "sw $26,104(%0)\n\t"    \
+               "sw $27,108(%0)\n\t"    \
+               "sw $28,112(%0)\n\t"    \
+               "sw $29,116(%0)\n\t"    \
+               "sw $30,120(%0)\n\t"    \
+               "sw $31,124(%0)\n\t"    \
+               : : "r" (&(ctx).sc_regs [0])    \
+               : "memory"                      \
+       )
+
 #elif defined(__s390x__)
 
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
@@ -375,8 +523,8 @@ typedef struct ucontext MonoContext;
        } while (0) 
 
 #define MONO_CONTEXT_GET_IP(ctx) (gpointer) (ctx)->uc_mcontext.psw.addr
-#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15]))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[11]))
 
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \