[runtime] Fix scanning of SIMD registers on Mac.
authorJon Purdy <evincarofautumn@gmail.com>
Fri, 29 Jul 2016 00:18:55 +0000 (17:18 -0700)
committerJon Purdy <evincarofautumn@gmail.com>
Mon, 31 Oct 2016 22:03:10 +0000 (15:03 -0700)
Include XMM regs in context. Use names instead of hardcoded offsets.

mono/mini/mini-darwin.c
mono/mini/tramp-amd64.c
mono/utils/mach-support-amd64.c
mono/utils/mach-support-x86.c
mono/utils/mach-support.h
mono/utils/mono-context.c
mono/utils/mono-context.h
mono/utils/mono-sigcontext.h
mono/utils/mono-threads-mach.c

index a52f5eb80d06aef3137d018ac67b0940961f8460..4e632071ce2028c991303e2b827a93e61e2f0d8a 100644 (file)
@@ -166,8 +166,8 @@ gboolean
 mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
 {
        kern_return_t ret;
-       mach_msg_type_number_t num_state;
-       thread_state_t state;
+       mach_msg_type_number_t num_state, num_fpstate;
+       thread_state_t state, fpstate;
        ucontext_t ctx;
        mcontext_t mctx;
        MonoJitTlsData *jit_tls;
@@ -183,15 +183,16 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo
        tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
 
        state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+       fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
        mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
 
        do {
-               ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+               ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
        } while (ret == KERN_ABORTED);
        if (ret != KERN_SUCCESS)
                return FALSE;
 
-       mono_mach_arch_thread_state_to_mcontext (state, mctx);
+       mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
        ctx.uc_mcontext = mctx;
 
        mono_sigctx_to_monoctx (&ctx, &tctx->ctx);
index 7d7cc41aa618c99bb060fd69eedcf9441ba4b559..03e2af6fd3943a8f6afcbb50c8c4994f98bde7f6 100644 (file)
@@ -881,7 +881,7 @@ mono_arch_get_plt_info_offset (guint8 *plt_entry, mgreg_t *regs, guint8 *code)
 guint8*
 mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot)
 {
-       int tramp_size = 256;
+       int tramp_size = 512;
        int i, framesize, ctx_offset, cfa_offset, gregs_offset;
        guint8 *code, *buf;
        GSList *unwind_ops = NULL;
index 1802ff79f5364d8301566717bc2da54b5bcad12d..179a4f7ed748199ed0f6ccc018a63957e7fde44a 100644 (file)
@@ -59,27 +59,30 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
        ctx->__ss = *arch_state;
+       ctx->__fs = *arch_fpstate;
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
        *arch_state = ctx->__ss;
+       *arch_fpstate = ctx->__fs;
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        context->gregs [AMD64_RAX] = arch_state->__rax;
        context->gregs [AMD64_RBX] = arch_state->__rbx;
        context->gregs [AMD64_RCX] = arch_state->__rcx;
@@ -96,6 +99,22 @@ mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *
        context->gregs [AMD64_R14] = arch_state->__r14;
        context->gregs [AMD64_R15] = arch_state->__r15;
        context->gregs [AMD64_RIP] = arch_state->__rip;
+       context->fregs [AMD64_XMM0] = arch_fpstate->__fpu_xmm0;
+       context->fregs [AMD64_XMM1] = arch_fpstate->__fpu_xmm1;
+       context->fregs [AMD64_XMM2] = arch_fpstate->__fpu_xmm2;
+       context->fregs [AMD64_XMM3] = arch_fpstate->__fpu_xmm3;
+       context->fregs [AMD64_XMM4] = arch_fpstate->__fpu_xmm4;
+       context->fregs [AMD64_XMM5] = arch_fpstate->__fpu_xmm5;
+       context->fregs [AMD64_XMM6] = arch_fpstate->__fpu_xmm6;
+       context->fregs [AMD64_XMM7] = arch_fpstate->__fpu_xmm7;
+       context->fregs [AMD64_XMM8] = arch_fpstate->__fpu_xmm8;
+       context->fregs [AMD64_XMM9] = arch_fpstate->__fpu_xmm9;
+       context->fregs [AMD64_XMM10] = arch_fpstate->__fpu_xmm10;
+       context->fregs [AMD64_XMM11] = arch_fpstate->__fpu_xmm11;
+       context->fregs [AMD64_XMM12] = arch_fpstate->__fpu_xmm12;
+       context->fregs [AMD64_XMM13] = arch_fpstate->__fpu_xmm13;
+       context->fregs [AMD64_XMM14] = arch_fpstate->__fpu_xmm14;
+       context->fregs [AMD64_XMM15] = arch_fpstate->__fpu_xmm15;
 }
 
 int
@@ -104,23 +123,39 @@ mono_mach_arch_get_thread_state_size ()
        return sizeof (x86_thread_state64_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       return sizeof (x86_float_state64_t);
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
-       x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_thread_state64_t *arch_state = (x86_thread_state64_t *)state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *)fpstate;
        kern_return_t ret;
 
        *count = x86_THREAD_STATE64_COUNT;
+       *fpcount = x86_FLOAT_STATE64_COUNT;
 
-       ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t) arch_state, count);
+       ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t)arch_state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
 
+       ret = thread_get_state (thread, x86_FLOAT_STATE64, (thread_state_t)arch_fpstate, fpcount);
        return ret;
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
-       return thread_set_state (thread, x86_THREAD_STATE64, state, count);
+       kern_return_t ret;
+       ret = thread_set_state (thread, x86_THREAD_STATE64, state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
+       ret = thread_set_state (thread, x86_FLOAT_STATE64, fpstate, fpcount);
+       return ret;
 }
 
 void *
index 3e8b166eaf2b51a7dc69f49d889c896762d75732..a296254cd2cffb17f92947fdbc9dce54f7aa1c4e 100644 (file)
@@ -16,6 +16,9 @@
 #include "utils/mono-sigcontext.h"
 #include "mach-support.h"
 
+// For reg numbers
+#include <mono/arch/amd64/amd64-codegen.h>
+
 /* Known offsets used for TLS storage*/
 
 /* All OSX versions up to 10.8 */
@@ -55,27 +58,30 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
        ctx->__ss = *arch_state;
+       ctx->__fs = *arch_fpstate;
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
        *arch_state = ctx->__ss;
+       *arch_fpstate = ctx->__fs;
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) state;
        context->eax = arch_state->__eax;
        context->ebx = arch_state->__ebx;
        context->ecx = arch_state->__ecx;
@@ -85,38 +91,62 @@ mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *
        context->esi = arch_state->__edi;
        context->edi = arch_state->__esi;
        context->eip = arch_state->__eip;
+       context->fregs [X86_XMM0] = arch_fpstate->__fpu_xmm0;
+       context->fregs [X86_XMM1] = arch_fpstate->__fpu_xmm1;
+       context->fregs [X86_XMM2] = arch_fpstate->__fpu_xmm2;
+       context->fregs [X86_XMM3] = arch_fpstate->__fpu_xmm3;
+       context->fregs [X86_XMM4] = arch_fpstate->__fpu_xmm4;
+       context->fregs [X86_XMM5] = arch_fpstate->__fpu_xmm5;
+       context->fregs [X86_XMM6] = arch_fpstate->__fpu_xmm6;
+       context->fregs [X86_XMM7] = arch_fpstate->__fpu_xmm7;
 }
 
-
 int
 mono_mach_arch_get_thread_state_size ()
 {
        return sizeof (x86_thread_state32_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       return sizeof (x86_float_state32_t);
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_get_state() is not supported by this platform");
 #else
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        kern_return_t ret;
 
        *count = x86_THREAD_STATE32_COUNT;
-       ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t) arch_state, count);
+       *fpcount = x86_FLOAT_STATE32_COUNT;
+
+       ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t)arch_state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
 
+       ret = thread_get_state (thread, x86_FLOAT_STATE32, (thread_state_t)arch_fpstate, fpcount);
        return ret;
 #endif
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_set_state() is not supported by this platform");
 #else
-       return thread_set_state (thread, x86_THREAD_STATE32, state, count);
+       kern_return_t ret;
+       ret = thread_set_state (thread, x86_THREAD_STATE32, state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
+       ret = thread_set_state (thread, x86_FLOAT_STATE32, fpstate, fpcount);
+       return ret;
 #endif 
 }
 
index abc135bd4eb8eb9987db2bb56f5bbf6aadf59093..9ac334c7171a729dbbf5bfbca16b6da1e4291087 100644 (file)
@@ -29,15 +29,17 @@ void *mono_mach_arch_get_sp (thread_state_t state);
 void mono_mach_init (pthread_key_t key);
 
 int mono_mach_arch_get_mcontext_size (void);
-void mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context);
-void mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state);
-void mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context);
+void mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context);
+void mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate);
+void mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context);
 
+/* FIXME: Should return size_t, not int. */
 int mono_mach_arch_get_thread_state_size (void);
+int mono_mach_arch_get_thread_fpstate_size (void);
 kern_return_t mono_mach_get_threads (thread_act_array_t *threads, guint32 *count);
 kern_return_t mono_mach_free_threads (thread_act_array_t threads, guint32 count);
-kern_return_t mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count);
-kern_return_t mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count);
+kern_return_t mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount);
+kern_return_t mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount);
 void *mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key);
 void *mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key);
 
index 632513d874f7c8069bd6a1ee0d57c23b1c06bdd3..3056c3afd3a63e31ed39b746dabc589cc0ccc6a1 100644 (file)
@@ -170,6 +170,26 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
        mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
        mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
+
+#ifdef UCONTEXT_REG_XMM
+       mctx->fregs [0] = UCONTEXT_REG_XMM0 (ctx);
+       mctx->fregs [1] = UCONTEXT_REG_XMM1 (ctx);
+       mctx->fregs [2] = UCONTEXT_REG_XMM2 (ctx);
+       mctx->fregs [3] = UCONTEXT_REG_XMM3 (ctx);
+       mctx->fregs [4] = UCONTEXT_REG_XMM4 (ctx);
+       mctx->fregs [5] = UCONTEXT_REG_XMM5 (ctx);
+       mctx->fregs [6] = UCONTEXT_REG_XMM6 (ctx);
+       mctx->fregs [7] = UCONTEXT_REG_XMM7 (ctx);
+       mctx->fregs [8] = UCONTEXT_REG_XMM8 (ctx);
+       mctx->fregs [9] = UCONTEXT_REG_XMM9 (ctx);
+       mctx->fregs [10] = UCONTEXT_REG_XMM10 (ctx);
+       mctx->fregs [11] = UCONTEXT_REG_XMM11 (ctx);
+       mctx->fregs [12] = UCONTEXT_REG_XMM12 (ctx);
+       mctx->fregs [13] = UCONTEXT_REG_XMM13 (ctx);
+       mctx->fregs [14] = UCONTEXT_REG_XMM14 (ctx);
+       mctx->fregs [15] = UCONTEXT_REG_XMM15 (ctx);
+#endif
+
 #elif defined(HOST_WIN32)
        CONTEXT *context = (CONTEXT*)sigctx;
 
@@ -224,6 +244,26 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
        UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
        UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
+
+#ifdef UCONTEXT_REG_XMM
+       UCONTEXT_REG_XMM0 (ctx) = mctx->fregs [0];
+       UCONTEXT_REG_XMM1 (ctx) = mctx->fregs [1];
+       UCONTEXT_REG_XMM2 (ctx) = mctx->fregs [2];
+       UCONTEXT_REG_XMM3 (ctx) = mctx->fregs [3];
+       UCONTEXT_REG_XMM4 (ctx) = mctx->fregs [4];
+       UCONTEXT_REG_XMM5 (ctx) = mctx->fregs [5];
+       UCONTEXT_REG_XMM6 (ctx) = mctx->fregs [6];
+       UCONTEXT_REG_XMM7 (ctx) = mctx->fregs [7];
+       UCONTEXT_REG_XMM8 (ctx) = mctx->fregs [8];
+       UCONTEXT_REG_XMM9 (ctx) = mctx->fregs [9];
+       UCONTEXT_REG_XMM10 (ctx) = mctx->fregs [10];
+       UCONTEXT_REG_XMM11 (ctx) = mctx->fregs [11];
+       UCONTEXT_REG_XMM12 (ctx) = mctx->fregs [12];
+       UCONTEXT_REG_XMM13 (ctx) = mctx->fregs [13];
+       UCONTEXT_REG_XMM14 (ctx) = mctx->fregs [14];
+       UCONTEXT_REG_XMM15 (ctx) = mctx->fregs [15];
+#endif
+
 #elif defined(HOST_WIN32)
        CONTEXT *context = (CONTEXT*)sigctx;
 
index 0a1bd524cfd42261ac798b6f0b2eb1b8c7fe726f..860589e74b0c5f410e83cb07e130d5a33a78882f 100644 (file)
 #include <signal.h>
 #endif
 
+#define MONO_CONTEXT_OFFSET(field, index, field_type) \
+    "i" (offsetof (MonoContext, field) + (index) * sizeof (field_type))
+
+#if defined(__APPLE__)
+typedef struct __darwin_xmm_reg MonoContextSimdReg;
+#endif
+
 /*
  * General notes about mono-context.
  * Each arch defines a MonoContext struct with all GPR regs + IP/PC.
@@ -87,6 +94,8 @@ struct sigcontext {
 # define SC_ESI esi
 #endif
 
+#include <mono/arch/x86/x86-codegen.h>
+
 typedef struct {
        mgreg_t eax;
        mgreg_t ebx;
@@ -97,6 +106,9 @@ typedef struct {
        mgreg_t esi;
        mgreg_t edi;
        mgreg_t eip;
+#ifdef __APPLE__
+    MonoContextSimdReg fregs [X86_XMM_NREG];
+#endif
 } MonoContext;
 
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (mgreg_t)(ip); } while (0); 
@@ -129,18 +141,26 @@ typedef struct {
 #else
 #define MONO_CONTEXT_GET_CURRENT(ctx) \
        __asm__ __volatile__(   \
-       "movl $0x0, 0x00(%0)\n" \
-       "mov %%ebx, 0x04(%0)\n" \
-       "mov %%ecx, 0x08(%0)\n" \
-       "mov %%edx, 0x0c(%0)\n" \
-       "mov %%ebp, 0x10(%0)\n" \
-       "mov %%esp, 0x14(%0)\n" \
-       "mov %%esi, 0x18(%0)\n" \
-       "mov %%edi, 0x1c(%0)\n" \
+       "movl $0x0, %c[eax](%0)\n" \
+       "mov %%ebx, %c[ebx](%0)\n" \
+       "mov %%ecx, %c[ecx](%0)\n" \
+       "mov %%edx, %c[edx](%0)\n" \
+       "mov %%ebp, %c[ebp](%0)\n" \
+       "mov %%esp, %c[esp](%0)\n" \
+       "mov %%esi, %c[esi](%0)\n" \
+       "mov %%edi, %c[edi](%0)\n" \
        "call 1f\n"     \
        "1: pop 0x20(%0)\n"     \
        :       \
-       : "a" (&(ctx))  \
+       : "a" (&(ctx)), \
+               [eax] MONO_CONTEXT_OFFSET (eax, 0, mgreg_t), \
+               [ebx] MONO_CONTEXT_OFFSET (ebx, 0, mgreg_t), \
+               [ecx] MONO_CONTEXT_OFFSET (ecx, 0, mgreg_t), \
+               [edx] MONO_CONTEXT_OFFSET (edx, 0, mgreg_t), \
+               [ebp] MONO_CONTEXT_OFFSET (ebp, 0, mgreg_t), \
+               [esp] MONO_CONTEXT_OFFSET (esp, 0, mgreg_t), \
+               [esi] MONO_CONTEXT_OFFSET (esi, 0, mgreg_t), \
+               [edi] MONO_CONTEXT_OFFSET (edi, 0, mgreg_t) \
        : "memory")
 #endif
 
@@ -160,7 +180,11 @@ typedef struct {
 
 typedef struct {
        mgreg_t gregs [AMD64_NREG];
+#ifdef __APPLE__
+       MonoContextSimdReg fregs [AMD64_XMM_NREG];
+#else
        double fregs [AMD64_XMM_NREG];
+#endif
 } MonoContext;
 
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->gregs [AMD64_RIP] = (mgreg_t)(ip); } while (0);
@@ -202,30 +226,98 @@ extern void mono_context_get_current (void *);
                : "rdx", "memory")
 #else
 
-#define MONO_CONTEXT_GET_CURRENT(ctx)  \
-       __asm__ __volatile__(   \
-               "movq $0x0,  0x00(%0)\n"        \
-               "movq %%rcx, 0x08(%0)\n"        \
-               "movq %%rdx, 0x10(%0)\n"        \
-               "movq %%rbx, 0x18(%0)\n"        \
-               "movq %%rsp, 0x20(%0)\n"        \
-               "movq %%rbp, 0x28(%0)\n"        \
-               "movq %%rsi, 0x30(%0)\n"        \
-               "movq %%rdi, 0x38(%0)\n"        \
-               "movq %%r8,  0x40(%0)\n"        \
-               "movq %%r9,  0x48(%0)\n"        \
-               "movq %%r10, 0x50(%0)\n"        \
-               "movq %%r11, 0x58(%0)\n"        \
-               "movq %%r12, 0x60(%0)\n"        \
-               "movq %%r13, 0x68(%0)\n"        \
-               "movq %%r14, 0x70(%0)\n"        \
-               "movq %%r15, 0x78(%0)\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")
+#define MONO_CONTEXT_GET_CURRENT_GREGS(ctx) \
+       do { \
+               __asm__ __volatile__(   \
+                       "movq $0x0,  %c[rax](%0)\n"     \
+                       "movq %%rcx, %c[rcx](%0)\n"     \
+                       "movq %%rdx, %c[rdx](%0)\n"     \
+                       "movq %%rbx, %c[rbx](%0)\n"     \
+                       "movq %%rsp, %c[rsp](%0)\n"     \
+                       "movq %%rbp, %c[rbp](%0)\n"     \
+                       "movq %%rsi, %c[rsi](%0)\n"     \
+                       "movq %%rdi, %c[rdi](%0)\n"     \
+                       "movq %%r8,  %c[r8](%0)\n"      \
+                       "movq %%r9,  %c[r9](%0)\n"      \
+                       "movq %%r10, %c[r10](%0)\n"     \
+                       "movq %%r11, %c[r11](%0)\n"     \
+                       "movq %%r12, %c[r12](%0)\n"     \
+                       "movq %%r13, %c[r13](%0)\n"     \
+                       "movq %%r14, %c[r14](%0)\n"     \
+                       "movq %%r15, %c[r15](%0)\n"     \
+                       /* "leaq (%%rip), %%rdx\n" is not understood by icc */  \
+                       ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
+                       "movq %%rdx, %c[rip](%0)\n"     \
+                       :       \
+                       : "a" (&(ctx)), \
+                               [rax] MONO_CONTEXT_OFFSET (gregs, AMD64_RAX, mgreg_t),  \
+                               [rcx] MONO_CONTEXT_OFFSET (gregs, AMD64_RCX, mgreg_t),  \
+                               [rdx] MONO_CONTEXT_OFFSET (gregs, AMD64_RDX, mgreg_t),  \
+                               [rbx] MONO_CONTEXT_OFFSET (gregs, AMD64_RBX, mgreg_t),  \
+                               [rsp] MONO_CONTEXT_OFFSET (gregs, AMD64_RSP, mgreg_t),  \
+                               [rbp] MONO_CONTEXT_OFFSET (gregs, AMD64_RBP, mgreg_t),  \
+                               [rsi] MONO_CONTEXT_OFFSET (gregs, AMD64_RSI, mgreg_t),  \
+                               [rdi] MONO_CONTEXT_OFFSET (gregs, AMD64_RDI, mgreg_t),  \
+                               [r8] MONO_CONTEXT_OFFSET (gregs, AMD64_R8, mgreg_t), \
+                               [r9] MONO_CONTEXT_OFFSET (gregs, AMD64_R9, mgreg_t), \
+                               [r10] MONO_CONTEXT_OFFSET (gregs, AMD64_R10, mgreg_t),  \
+                               [r11] MONO_CONTEXT_OFFSET (gregs, AMD64_R11, mgreg_t),  \
+                               [r12] MONO_CONTEXT_OFFSET (gregs, AMD64_R12, mgreg_t),  \
+                               [r13] MONO_CONTEXT_OFFSET (gregs, AMD64_R13, mgreg_t),  \
+                               [r14] MONO_CONTEXT_OFFSET (gregs, AMD64_R14, mgreg_t),  \
+                               [r15] MONO_CONTEXT_OFFSET (gregs, AMD64_R15, mgreg_t),  \
+                               [rip] MONO_CONTEXT_OFFSET (gregs, AMD64_RIP, mgreg_t)   \
+                       : "rdx", "memory");     \
+       } while (0)
+
+#ifdef UCONTEXT_REG_XMM
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx) \
+       do { \
+               __asm__ __volatile__ ( \
+                       "movups %%xmm0, %c[xmm0](%0)\n" \
+                       "movups %%xmm1, %c[xmm1](%0)\n" \
+                       "movups %%xmm2, %c[xmm2](%0)\n" \
+                       "movups %%xmm3, %c[xmm3](%0)\n" \
+                       "movups %%xmm4, %c[xmm4](%0)\n" \
+                       "movups %%xmm5, %c[xmm5](%0)\n" \
+                       "movups %%xmm6, %c[xmm6](%0)\n" \
+                       "movups %%xmm7, %c[xmm7](%0)\n" \
+                       "movups %%xmm8, %c[xmm8](%0)\n" \
+                       "movups %%xmm9, %c[xmm9](%0)\n" \
+                       "movups %%xmm10, %c[xmm10](%0)\n"       \
+                       "movups %%xmm11, %c[xmm11](%0)\n"       \
+                       "movups %%xmm12, %c[xmm12](%0)\n"       \
+                       "movups %%xmm12, %c[xmm12](%0)\n"       \
+                       "movups %%xmm14, %c[xmm14](%0)\n"       \
+                       "movups %%xmm15, %c[xmm15](%0)\n"       \
+                       : \
+                       : "a" (&(ctx)), \
+                               [xmm0] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM0, MonoContextSimdReg), \
+                               [xmm1] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM1, MonoContextSimdReg), \
+                               [xmm2] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM2, MonoContextSimdReg), \
+                               [xmm3] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM3, MonoContextSimdReg), \
+                               [xmm4] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM4, MonoContextSimdReg), \
+                               [xmm5] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM5, MonoContextSimdReg), \
+                               [xmm6] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM6, MonoContextSimdReg), \
+                               [xmm7] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM7, MonoContextSimdReg), \
+                               [xmm8] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM8, MonoContextSimdReg), \
+                               [xmm9] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM9, MonoContextSimdReg), \
+                               [xmm10] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM10, MonoContextSimdReg), \
+                               [xmm11] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM11, MonoContextSimdReg), \
+                               [xmm12] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM12, MonoContextSimdReg), \
+                               [xmm13] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM13, MonoContextSimdReg), \
+                               [xmm14] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM14, MonoContextSimdReg), \
+                               [xmm15] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM15, MonoContextSimdReg));  \
+       } while (0)
+#else
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx)
+#endif
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) \
+    do {       \
+               MONO_CONTEXT_GET_CURRENT_GREGS(ctx);    \
+               MONO_CONTEXT_GET_CURRENT_FREGS(ctx);    \
+       } while (0)
 #endif
 
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
index 3c2f79b58c37e99ac92e90325b6f603118182aaa..643bb4d7709a9f7299bd8b039e7665d6e058921c 100644 (file)
@@ -173,6 +173,23 @@ typedef struct ucontext {
        #define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r13)
        #define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r14)
        #define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r15)
+       #define UCONTEXT_REG_XMM
+       #define UCONTEXT_REG_XMM0(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm0)
+       #define UCONTEXT_REG_XMM1(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm1)
+       #define UCONTEXT_REG_XMM2(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm2)
+       #define UCONTEXT_REG_XMM3(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm3)
+       #define UCONTEXT_REG_XMM4(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm4)
+       #define UCONTEXT_REG_XMM5(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm5)
+       #define UCONTEXT_REG_XMM6(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm6)
+       #define UCONTEXT_REG_XMM7(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm7)
+       #define UCONTEXT_REG_XMM8(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm8)
+       #define UCONTEXT_REG_XMM9(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm9)
+       #define UCONTEXT_REG_XMM10(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm10)
+       #define UCONTEXT_REG_XMM11(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm11)
+       #define UCONTEXT_REG_XMM12(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm12)
+       #define UCONTEXT_REG_XMM13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm13)
+       #define UCONTEXT_REG_XMM14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm14)
+       #define UCONTEXT_REG_XMM15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm15)
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        #define UCONTEXT_REG_RAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rax)
        #define UCONTEXT_REG_RBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rbx)
@@ -229,7 +246,7 @@ typedef struct ucontext {
        #define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->sc_r14)
        #define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->sc_r15)
 #elif !defined(HOST_WIN32)
-#define UCONTEXT_GREGS(ctx)    ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
+       #define UCONTEXT_GREGS(ctx)     ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
 #endif
 
 #ifdef UCONTEXT_GREGS
index b696064decdc986ea5305ef39a4aa4ee5a45242e..fdf18bb1891eeb47c08ec7e6176341912fe57b03 100644 (file)
@@ -117,8 +117,8 @@ mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
 
        if (info->async_target) {
                MonoContext tmp = info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx;
-               mach_msg_type_number_t num_state;
-               thread_state_t state;
+               mach_msg_type_number_t num_state, num_fpstate;
+               thread_state_t state, fpstate;
                ucontext_t uctx;
                mcontext_t mctx;
 
@@ -127,23 +127,24 @@ mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
                info->async_target = (void (*)(void *)) info->user_data;
 
                state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+               fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
                mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
 
                do {
-                       ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+                       ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
                } while (ret == KERN_ABORTED);
 
                if (ret != KERN_SUCCESS)
                        return FALSE;
 
-               mono_mach_arch_thread_state_to_mcontext (state, mctx);
+               mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
                uctx.uc_mcontext = mctx;
                mono_monoctx_to_sigctx (&tmp, &uctx);
 
-               mono_mach_arch_mcontext_to_thread_state (mctx, state);
+               mono_mach_arch_mcontext_to_thread_states (mctx, state, fpstate);
 
                do {
-                       ret = mono_mach_arch_set_thread_state (info->native_handle, state, num_state);
+                       ret = mono_mach_arch_set_thread_states (info->native_handle, state, num_state, fpstate, num_fpstate);
                } while (ret == KERN_ABORTED);
 
                if (ret != KERN_SUCCESS)