X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-amd64.h;h=b2f8934e66de12b1afe31b0471f5b0b062ac14cd;hb=5e229a24020c971c84c08ef8790c3fa3a9b92e5b;hp=b9ff7048586106bb7dd2ab7925440dd447d137c5;hpb=f166d355b6a897f35979b5183fa20be90713437a;p=mono.git diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index b9ff7048586..b2f8934e66d 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -47,6 +47,7 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep); #ifdef sun // Solaris x86 # undef SIGSEGV_ON_ALTSTACK +# define MONO_ARCH_NOMAP32BIT struct sigcontext { unsigned short gs, __gsh; @@ -73,13 +74,15 @@ struct sigcontext { }; #endif // sun, Solaris x86 -#define MONO_ARCH_SIGNAL_STACK_SIZE (64 * 1024) +#define MONO_ARCH_SIGNAL_STACK_SIZE (16 * 1024) + +#define MONO_ARCH_CPU_SPEC amd64_desc #define MONO_MAX_IREGS 16 #define MONO_MAX_FREGS AMD64_XMM_NREG -#define MONO_ARCH_HAS_XP_LOCAL_REGALLOC +#define MONO_ARCH_FP_RETURN_REG AMD64_XMM0 /* xmm15 is reserved for use by some opcodes */ #define MONO_ARCH_CALLEE_FREGS 0xef @@ -88,9 +91,8 @@ struct sigcontext { #define MONO_ARCH_CALLEE_REGS AMD64_CALLEE_REGS #define MONO_ARCH_CALLEE_SAVED_REGS AMD64_CALLEE_SAVED_REGS -/* Setting this to FALSE means using SSE2 instructions for fp arithmetic */ #define MONO_ARCH_USE_FPSTACK FALSE -#define MONO_ARCH_FPSTACK_SIZE 6 +#define MONO_ARCH_FPSTACK_SIZE 0 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == '\0') ? -1 : ((desc == 'i' ? -1 : ((desc == 'a') ? AMD64_RAX : ((desc == 's') ? AMD64_RCX : ((desc == 'd') ? AMD64_RDX : -1)))))) @@ -110,8 +112,6 @@ struct sigcontext { #define MONO_ARCH_RETREG1 X86_EAX #define MONO_ARCH_RETREG2 X86_EDX -#define MONO_ARCH_AOT_PLT_OFFSET_REG AMD64_RAX - #define MONO_ARCH_ENCODE_LREG(r1,r2) (r1 | (r2<<3)) #define inst_dreg_low dreg&7 @@ -122,17 +122,27 @@ struct sigcontext { #define inst_sreg2_high sreg2>>3 struct MonoLMF { + /* + * If the lowest bit is set to 1, then this LMF has the rip field set. Otherwise, + * the rip field is not set, and the rsp field points to the stack location where + * the caller ip is saved. + */ gpointer previous_lmf; gpointer lmf_addr; + /* This is only set in trampoline LMF frames */ MonoMethod *method; guint64 rip; guint64 rbx; - guint64 ebp; + guint64 rbp; guint64 rsp; guint64 r12; guint64 r13; guint64 r14; guint64 r15; +#ifdef PLATFORM_WIN32 + guint64 rdi; + guint64 rsi; +#endif }; typedef struct MonoCompileArch { @@ -141,6 +151,12 @@ typedef struct MonoCompileArch { gint32 reg_save_area_offset; gint32 stack_alloc_size; gboolean omit_fp, omit_fp_computed; + gpointer cinfo; + gint32 async_point_count; + gpointer vret_addr_loc; +#ifdef PLATFORM_WIN32 + gpointer unwindinfo; +#endif } MonoCompileArch; typedef struct { @@ -159,21 +175,43 @@ typedef struct { guint64 r15; } MonoContext; -#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->rip = (long)(ip); } while (0); -#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->rbp = (long)(bp); } while (0); -#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->rsp = (long)(esp); } while (0); +#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->rip = (guint64)(ip); } while (0); +#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->rbp = (guint64)(bp); } while (0); +#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->rsp = (guint64)(esp); } while (0); #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->rip)) #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->rbp)) #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->rsp)) +#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) + +#ifdef _MSC_VER + +#define MONO_INIT_CONTEXT_FROM_FUNC(ctx, start_func) do { \ + guint64 stackptr; \ + mono_arch_flush_register_windows (); \ + stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));\ + MONO_CONTEXT_SET_IP ((ctx), (start_func)); \ + MONO_CONTEXT_SET_BP ((ctx), stackptr); \ + MONO_CONTEXT_SET_SP ((ctx), stackptr); \ +} while (0) + +#else + +/* + * __builtin_frame_address () is broken on some older gcc versions in the presence of + * frame pointer elimination, see bug #82095. + */ #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do { \ + int tmp; \ + guint64 stackptr = (guint64)&tmp; \ mono_arch_flush_register_windows (); \ MONO_CONTEXT_SET_IP ((ctx), (start_func)); \ - MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \ + MONO_CONTEXT_SET_BP ((ctx), stackptr); \ + MONO_CONTEXT_SET_SP ((ctx), stackptr); \ } while (0) -#define MONO_ARCH_USE_SIGACTION 1 +#endif /* * some icalls like mono_array_new_va needs to be called using a different @@ -183,6 +221,8 @@ typedef struct { #ifndef PLATFORM_WIN32 +#define MONO_ARCH_USE_SIGACTION 1 + #ifdef HAVE_WORKING_SIGALTSTACK #define MONO_ARCH_SIGSEGV_ON_ALTSTACK @@ -223,7 +263,6 @@ typedef struct { #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS #define MONO_ARCH_EMULATE_CONV_R8_UN 1 -#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1 #define MONO_ARCH_EMULATE_FREM 1 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 @@ -232,14 +271,72 @@ typedef struct { #define MONO_ARCH_ENABLE_MONO_LMF_VAR 1 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1 -#define MONO_ARCH_HAVE_PIC_AOT 1 #define MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN 1 -#define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 -#define MONO_ARCH_HAVE_CREATE_VARS 1 +#define MONO_ARCH_HAVE_ATOMIC_ADD 1 +#define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1 +#define MONO_ARCH_HAVE_ATOMIC_CAS_IMM 1 +#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1 +#define MONO_ARCH_HAVE_IMT 1 +#define MONO_ARCH_HAVE_TLS_GET 1 +#define MONO_ARCH_IMT_REG AMD64_R11 +#define MONO_ARCH_VTABLE_REG AMD64_R11 +/* + * We use r10 for the rgctx register rather than r11 because r11 is + * used by the trampoline as a scratch register and hence might be + * clobbered across method call boundaries. + */ +#define MONO_ARCH_RGCTX_REG AMD64_R10 +#define MONO_ARCH_COMMON_VTABLE_TRAMPOLINE 1 +#define MONO_ARCH_HAVE_CMOV_OPS 1 +#define MONO_ARCH_HAVE_NOTIFY_PENDING_EXC 1 +#define MONO_ARCH_ENABLE_NORMALIZE_OPCODES 1 +#define MONO_ARCH_ENABLE_GLOBAL_RA 1 + +#define MONO_ARCH_AOT_SUPPORTED 1 + +/* Used for optimization, not complete */ +#define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE) + +#define MONO_ARCH_EMIT_BOUNDS_CHECK(cfg, array_reg, offset, index_reg) do { \ + MonoInst *inst; \ + MONO_INST_NEW ((cfg), inst, OP_AMD64_ICOMPARE_MEMBASE_REG); \ + inst->inst_basereg = array_reg; \ + inst->inst_offset = offset; \ + inst->sreg2 = index_reg; \ + MONO_ADD_INS ((cfg)->cbb, inst); \ + MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \ + } while (0) + +void +mono_amd64_patch (unsigned char* code, gpointer target) MONO_INTERNAL; + +void +mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, + guint64 dummy5, guint64 dummy6, + MonoObject *exc, guint64 rip, guint64 rsp, + guint64 rbx, guint64 rbp, guint64 r12, guint64 r13, + guint64 r14, guint64 r15, guint64 rdi, guint64 rsi, + guint64 rax, guint64 rcx, guint64 rdx, + guint64 rethrow); + +typedef struct { + guint8 *address; + guint8 saved_byte; +} MonoBreakpointInfo; + +extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE]; + +#ifdef PLATFORM_WIN32 + +void mono_arch_unwindinfo_add_push_nonvol (gpointer* monoui, gpointer codebegin, gpointer nextip, guchar reg ); +void mono_arch_unwindinfo_add_set_fpreg (gpointer* monoui, gpointer codebegin, gpointer nextip, guchar reg ); +void mono_arch_unwindinfo_add_alloc_stack (gpointer* monoui, gpointer codebegin, gpointer nextip, guint size ); +guint mono_arch_unwindinfo_get_size (gpointer* monoui); +void mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code, guint code_size); -gboolean -mono_amd64_is_sse2 (void); +#define MONO_ARCH_HAVE_UNWIND_TABLE 1 +#endif #endif /* __MONO_MINI_AMD64_H__ */