#define MONO_CONTEXT_OFFSET(field, index, field_type) \
"i" (offsetof (MonoContext, field) + (index) * sizeof (field_type))
+#if defined(TARGET_X86)
#if defined(__APPLE__)
typedef struct __darwin_xmm_reg MonoContextSimdReg;
#endif
+#elif defined(TARGET_AMD64)
+#if defined(__APPLE__)
+typedef struct __darwin_xmm_reg MonoContextSimdReg;
+#elif defined(__linux__)
+typedef struct _libc_xmmreg MonoContextSimdReg;
+#endif
+#elif defined(TARGET_ARM64)
+typedef __uint128_t MonoContextSimdReg;
+#endif
/*
* General notes about mono-context.
* 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__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
+#if defined (TARGET_WASM)
+
+typedef struct {
+ mgreg_t wasm_sp;
+ mgreg_t wasm_bp;
+ mgreg_t llvm_exc_reg;
+ mgreg_t wasm_ip;
+ mgreg_t wasm_pc;
+} MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->wasm_ip = (mgreg_t)(ip); } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->wasm_bp = (mgreg_t)(bp); } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->wasm_sp = (mgreg_t)(sp); } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->wasm_ip))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->wasm_bp))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->wasm_sp))
+
+#elif (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__) || \
#endif
#endif
-#if defined(__native_client__)
-#undef MONO_SIGNAL_USE_UCONTEXT_T
-#endif
-
#ifdef __HAIKU__
/* sigcontext surrogate */
struct sigcontext {
#include <mono/arch/amd64/amd64-codegen.h>
-#if !defined( HOST_WIN32 ) && !defined(__native_client__) && !defined(__native_client_codegen__)
+#if !defined( HOST_WIN32 )
#if defined(HAVE_SIGACTION) || defined(__APPLE__) // the __APPLE__ check is required for the tvos simulator, which has ucontext_t but not sigaction
#define MONO_SIGNAL_USE_UCONTEXT_T 1
typedef struct {
mgreg_t gregs [AMD64_NREG];
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__linux__)
MonoContextSimdReg fregs [AMD64_XMM_NREG];
#else
double fregs [AMD64_XMM_NREG];
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" \
- "movq %%rcx, %%nacl:0x08(%%r15, %0, 1)\n" \
- "movq %%rdx, %%nacl:0x10(%%r15, %0, 1)\n" \
- "movq %%rbx, %%nacl:0x18(%%r15, %0, 1)\n" \
- "movq %%rsp, %%nacl:0x20(%%r15, %0, 1)\n" \
- "movq %%rbp, %%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_GREGS(ctx) \
typedef struct {
mgreg_t regs [32];
- double fregs [32];
+ /* FIXME not fully saved in trampolines */
+ MonoContextSimdReg fregs [32];
mgreg_t pc;
/*
* fregs might not be initialized if this context was created from a
#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
arm_unified_thread_state_t thread_state; \
+ arm_neon_state64_t thread_fpstate; \
int state_flavor = ARM_UNIFIED_THREAD_STATE; \
+ int fpstate_flavor = ARM_NEON_STATE64; \
unsigned state_count = ARM_UNIFIED_THREAD_STATE_COUNT; \
+ unsigned fpstate_count = ARM_NEON_STATE64_COUNT; \
thread_port_t self = mach_thread_self (); \
kern_return_t ret = thread_get_state (self, state_flavor, (thread_state_t) &thread_state, &state_count); \
g_assert (ret == 0); \
- mono_mach_arch_thread_states_to_mono_context ((thread_state_t)&thread_state, (thread_state_t)NULL, &ctx); \
+ ret = thread_get_state (self, fpstate_flavor, (thread_state_t) &thread_fpstate, &fpstate_count); \
+ g_assert (ret == 0); \
+ mono_mach_arch_thread_states_to_mono_context ((thread_state_t) &thread_state, (thread_state_t) &thread_fpstate, &ctx); \
mach_port_deallocate (current_task (), self); \
} while (0);
"stp x30, xzr, [x16], #8\n" \
"mov x30, sp\n" \
"str x30, [x16], #8\n" \
- "stp d0, d1, [x16], #16\n" \
- "stp d2, d3, [x16], #16\n" \
- "stp d4, d5, [x16], #16\n" \
- "stp d6, d7, [x16], #16\n" \
- "stp d8, d9, [x16], #16\n" \
- "stp d10, d11, [x16], #16\n" \
- "stp d12, d13, [x16], #16\n" \
- "stp d14, d15, [x16], #16\n" \
- "stp d16, d17, [x16], #16\n" \
- "stp d18, d19, [x16], #16\n" \
- "stp d20, d21, [x16], #16\n" \
- "stp d22, d23, [x16], #16\n" \
- "stp d24, d25, [x16], #16\n" \
- "stp d26, d27, [x16], #16\n" \
- "stp d28, d29, [x16], #16\n" \
- "stp d30, d31, [x16], #16\n" \
+ "stp q0, q1, [x16], #32\n" \
+ "stp q2, q3, [x16], #32\n" \
+ "stp q4, q5, [x16], #32\n" \
+ "stp q6, q7, [x16], #32\n" \
+ "stp q8, q9, [x16], #32\n" \
+ "stp q10, q11, [x16], #32\n" \
+ "stp q12, q13, [x16], #32\n" \
+ "stp q14, q15, [x16], #32\n" \
+ "stp q16, q17, [x16], #32\n" \
+ "stp q18, q19, [x16], #32\n" \
+ "stp q20, q21, [x16], #32\n" \
+ "stp q22, q23, [x16], #32\n" \
+ "stp q24, q25, [x16], #32\n" \
+ "stp q26, q27, [x16], #32\n" \
+ "stp q28, q29, [x16], #32\n" \
+ "stp q30, q31, [x16], #32\n" \
: \
: "r" (&ctx.regs) \
: "x16", "x30", "memory" \
#define MONO_ARCH_HAS_MONO_CONTEXT 1
-#elif defined(__ia64__) /*defined(__sparc__) || defined(sparc) */
-
-#ifndef UNW_LOCAL_ONLY
-
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
-
-#endif
-
-typedef struct MonoContext {
- unw_cursor_t cursor;
- /* Whenever the ip in 'cursor' points to the ip where the exception happened */
- /* This is true for the initial context for exceptions thrown from signal handlers */
- gboolean precise_ip;
-} MonoContext;
-
-/*XXX SET_BP is missing*/
-#define MONO_CONTEXT_SET_IP(ctx,eip) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_IP, (unw_word_t)(eip)); g_assert (err == 0); } while (0)
-#define MONO_CONTEXT_SET_SP(ctx,esp) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_SP, (unw_word_t)(esp)); g_assert (err == 0); } while (0)
-
-#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)(mono_ia64_context_get_ip ((ctx))))
-#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)(mono_ia64_context_get_fp ((ctx))))
-#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)(mono_ia64_context_get_sp ((ctx))))
-
-static inline unw_word_t
-mono_ia64_context_get_ip (MonoContext *ctx)
-{
- unw_word_t ip;
- int err;
-
- err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
- g_assert (err == 0);
-
- if (ctx->precise_ip) {
- return ip;
- } else {
- /* Subtrack 1 so ip points into the actual instruction */
- return ip - 1;
- }
-}
-
-static inline unw_word_t
-mono_ia64_context_get_sp (MonoContext *ctx)
-{
- unw_word_t sp;
- int err;
-
- err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
- g_assert (err == 0);
-
- return sp;
-}
-
-static inline unw_word_t
-mono_ia64_context_get_fp (MonoContext *ctx)
-{
- unw_cursor_t new_cursor;
- unw_word_t fp;
- int err;
-
- {
- unw_word_t ip, sp;
-
- err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
- g_assert (err == 0);
-
- err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
- g_assert (err == 0);
- }
-
- /* fp is the SP of the parent frame */
- new_cursor = ctx->cursor;
-
- err = unw_step (&new_cursor);
- g_assert (err >= 0);
-
- err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp);
- g_assert (err == 0);
-
- return fp;
-}
-
-#elif ((defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */
+#elif ((defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))) && SIZEOF_REGISTER == 4
#define MONO_ARCH_HAS_MONO_CONTEXT 1