X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-amd64.h;h=becdaaa39ec0a1883a48d8be6d9c04364c65c2d0;hb=92f60fbffa1187be7dedf6a9286b5c35b2082815;hp=f9f90ac9357587e69c77eed4c93bb38eb65d815e;hpb=76f591ec1cc62732da4db1a2b1c9071021c4d8ed;p=mono.git diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index f9f90ac9357..becdaaa39ec 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -2,15 +2,17 @@ #define __MONO_MINI_AMD64_H__ #include +#include #include -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 #include /* use SIG* defines if possible */ #ifdef HAVE_SIGNAL_H #include #endif + /* sigcontext surrogate */ struct sigcontext { guint64 eax; @@ -24,7 +26,7 @@ struct sigcontext { guint64 eip; }; -typedef void (* MonoW32ExceptionHandler) (int); +typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_RECORD *info, void *context); void win32_seh_init(void); void win32_seh_cleanup(void); void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler); @@ -43,7 +45,7 @@ void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler); LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep); -#endif /* PLATFORM_WIN32 */ +#endif /* HOST_WIN32 */ #ifdef sun // Solaris x86 # undef SIGSEGV_ON_ALTSTACK @@ -74,18 +76,38 @@ struct sigcontext { }; #endif // sun, Solaris x86 +#define MONO_ARCH_SUPPORT_SIMD_INTRINSICS 1 + +#ifndef DISABLE_SIMD +#define MONO_ARCH_SIMD_INTRINSICS 1 +#define MONO_ARCH_NEED_SIMD_BANK 1 +#define MONO_ARCH_USE_SHARED_FP_SIMD_BANK 1 +#endif + + + #define MONO_ARCH_SIGNAL_STACK_SIZE (16 * 1024) +#define MONO_ARCH_HAVE_RESTORE_STACK_SUPPORT 1 + #define MONO_ARCH_CPU_SPEC amd64_desc #define MONO_MAX_IREGS 16 #define MONO_MAX_FREGS AMD64_XMM_NREG +#define MONO_ARCH_FP_RETURN_REG AMD64_XMM0 + /* xmm15 is reserved for use by some opcodes */ -#define MONO_ARCH_CALLEE_FREGS 0xef +#define MONO_ARCH_CALLEE_FREGS 0x7fff #define MONO_ARCH_CALLEE_SAVED_FREGS 0 +#define MONO_MAX_XREGS MONO_MAX_FREGS + +#define MONO_ARCH_CALLEE_XREGS 0x7fff +#define MONO_ARCH_CALLEE_SAVED_XREGS 0 + + #define MONO_ARCH_CALLEE_REGS AMD64_CALLEE_REGS #define MONO_ARCH_CALLEE_SAVED_REGS AMD64_CALLEE_SAVED_REGS @@ -106,26 +128,19 @@ struct sigcontext { * reproduceable results for benchmarks */ #define MONO_ARCH_CODE_ALIGNMENT 32 -#define MONO_ARCH_BASEREG X86_EBP #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 -#define inst_dreg_high dreg>>3 -#define inst_sreg1_low sreg1&7 -#define inst_sreg1_high sreg1>>3 -#define inst_sreg2_low sreg2&7 -#define inst_sreg2_high sreg2>>3 +/*This is the max size of the locals area of a given frame. I think 1MB is a safe default for now*/ +#define MONO_ARCH_MAX_FRAME_SIZE 0x100000 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. + * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and + * the other fields are not valid. */ gpointer previous_lmf; gpointer lmf_addr; @@ -139,7 +154,7 @@ struct MonoLMF { guint64 r13; guint64 r14; guint64 r15; -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 guint64 rdi; guint64 rsi; #endif @@ -150,9 +165,14 @@ typedef struct MonoCompileArch { gint32 localloc_offset; gint32 reg_save_area_offset; gint32 stack_alloc_size; - gboolean omit_fp, omit_fp_computed; + gboolean omit_fp, omit_fp_computed, no_pushes; gpointer cinfo; gint32 async_point_count; + gpointer vret_addr_loc; +#ifdef HOST_WIN32 + gpointer unwindinfo; +#endif + gpointer ss_trigger_page_var; } MonoCompileArch; typedef struct { @@ -179,6 +199,8 @@ typedef struct { #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->rbp)) #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->rsp)) +#define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->rax = (gsize)exc; } while (0) + #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) #ifdef _MSC_VER @@ -209,13 +231,22 @@ typedef struct { #endif +/* + * This structure is an extension of MonoLMF and contains extra information. + */ +typedef struct { + struct MonoLMF lmf; + gboolean debugger_invoke; + MonoContext ctx; /* if debugger_invoke is TRUE */ +} MonoLMFExt; + /* * some icalls like mono_array_new_va needs to be called using a different * calling convention. */ #define MONO_ARCH_VARARG_ICALLS 1 -#ifndef PLATFORM_WIN32 +#ifndef HOST_WIN32 #define MONO_ARCH_USE_SIGACTION 1 @@ -225,9 +256,39 @@ typedef struct { #endif -#endif /* PLATFORM_WIN32 */ +#endif /* HOST_WIN32 */ + +#if defined (__APPLE__) + +#define MONO_ARCH_NOMAP32BIT + +#elif defined (__NetBSD__) + +#define REG_RAX 14 +#define REG_RCX 3 +#define REG_RDX 2 +#define REG_RBX 13 +#define REG_RSP 24 +#define REG_RBP 12 +#define REG_RSI 1 +#define REG_RDI 0 +#define REG_R8 4 +#define REG_R9 5 +#define REG_R10 6 +#define REG_R11 7 +#define REG_R12 8 +#define REG_R13 9 +#define REG_R14 10 +#define REG_R15 11 +#define REG_RIP 21 + +#define MONO_ARCH_NOMAP32BIT + +#elif defined (__OpenBSD__) -#ifdef __FreeBSD__ +#define MONO_ARCH_NOMAP32BIT + +#elif defined (__FreeBSD__) #define REG_RAX 7 #define REG_RCX 4 @@ -255,6 +316,14 @@ typedef struct { #endif /* __FreeBSD__ */ +#ifdef HOST_WIN32 +#define MONO_AMD64_ARG_REG1 AMD64_RCX +#define MONO_AMD64_ARG_REG2 AMD64_RDX +#else +#define MONO_AMD64_ARG_REG1 AMD64_RDI +#define MONO_AMD64_ARG_REG2 AMD64_RSI +#endif + #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS @@ -262,34 +331,101 @@ typedef struct { #define MONO_ARCH_EMULATE_FREM 1 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 -#define MONO_ARCH_ENABLE_EMIT_STATE_OPT 1 #define MONO_ARCH_ENABLE_REGALLOC_IN_EH_BLOCKS 1 #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_CREATE_TRAMPOLINE_FROM_TOKEN 1 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 #define MONO_ARCH_HAVE_ATOMIC_ADD 1 #define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1 +#define MONO_ARCH_HAVE_ATOMIC_CAS 1 +#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1 +#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES_2 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 +#define MONO_ARCH_IMT_REG AMD64_R10 +#define MONO_ARCH_VTABLE_REG MONO_AMD64_ARG_REG1 /* - * We use r10 for the rgctx register rather than r11 because r11 is + * We use r10 for the imt/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_HAVE_EXCEPTIONS_INIT 1 +#define MONO_ARCH_ENABLE_GLOBAL_RA 1 +#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 +#define MONO_ARCH_HAVE_LIVERANGE_OPS 1 +#define MONO_ARCH_HAVE_XP_UNWIND 1 +#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 +#if !defined(HOST_WIN32) +#define MONO_ARCH_MONITOR_OBJECT_REG MONO_AMD64_ARG_REG1 +#endif +#define MONO_ARCH_HAVE_STATIC_RGCTX_TRAMPOLINE 1 +#define MONO_ARCH_HAVE_GET_TRAMPOLINES 1 #define MONO_ARCH_AOT_SUPPORTED 1 +#ifndef HOST_WIN32 +#define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 +#else +#define DISABLE_DEBUGGER_AGENT 1 +#endif +#define MONO_ARCH_HAVE_FIND_JIT_INFO_EXT 1 + +#if !defined(HOST_WIN32) || defined(__sun) +#define MONO_ARCH_ENABLE_MONITOR_IL_FASTPATH 1 +#endif + +#define MONO_ARCH_SUPPORT_TASKLETS 1 + +#ifndef HOST_WIN32 +#define MONO_AMD64_NO_PUSHES 1 +#endif + +#define MONO_ARCH_GSHARED_SUPPORTED 1 +#define MONO_ARCH_DYN_CALL_SUPPORTED 1 +#define MONO_ARCH_DYN_CALL_PARAM_AREA 0 + +#define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1 +#define MONO_ARCH_LLVM_SUPPORTED 1 +#define MONO_ARCH_THIS_AS_FIRST_ARG 1 + +#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_metadata_signature_equal ((caller_sig), (callee_sig)) + +/* 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, + mgreg_t *regs, mgreg_t rip, + MonoObject *exc, gboolean rethrow) MONO_INTERNAL; + +void +mono_amd64_throw_corlib_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, + guint64 dummy5, guint64 dummy6, + mgreg_t *regs, mgreg_t rip, + guint32 ex_token_index, gint64 pc_offset) MONO_INTERNAL; + +guint64 +mono_amd64_get_original_ip (void) MONO_INTERNAL; + +guint8* +mono_amd64_emit_tls_get (guint8* code, int dreg, int tls_offset) MONO_INTERNAL; + typedef struct { guint8 *address; guint8 saved_byte; @@ -297,5 +433,16 @@ typedef struct { extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE]; +#ifdef HOST_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); + +#define MONO_ARCH_HAVE_UNWIND_TABLE 1 +#endif + #endif /* __MONO_MINI_AMD64_H__ */