Merge pull request #2720 from mono/fix-39325
[mono.git] / mono / mini / mini-amd64.h
index 2b1f88dcb348d296c2309ab6095a83447e39d5f3..c22c9be0fd0007b3969fc7beec42ac686e66e0d9 100644 (file)
@@ -215,12 +215,39 @@ typedef struct MonoCompileArch {
 
 #ifdef TARGET_WIN32
 #define PARAM_REGS 4
+#define FLOAT_PARAM_REGS 4
+
+static AMD64_Reg_No param_regs [] = { AMD64_RCX, AMD64_RDX, AMD64_R8, AMD64_R9 };
+
+static AMD64_Reg_No return_regs [] = { AMD64_RAX, AMD64_RDX };
 #else
 #define PARAM_REGS 6
+#define FLOAT_PARAM_REGS 8
+
+static AMD64_Reg_No param_regs [] = { AMD64_RDI, AMD64_RSI, AMD64_RDX, AMD64_RCX, AMD64_R8, AMD64_R9 };
+
+static AMD64_Reg_No return_regs [] = { AMD64_RAX, AMD64_RDX };
 #endif
 
 typedef struct {
-       int dummy;
+       /* Method address to call */
+       gpointer addr;
+       /* The trampoline reads this, so keep the size explicit */
+       int ret_marshal;
+       /* If ret_marshal != NONE, this is the reg of the vret arg, else -1 (used in out case) */
+       /* Equivalent of vret_arg_slot in the x86 implementation. */
+       int vret_arg_reg;
+       /* The stack slot where the return value will be stored (used in in case) */
+       int vret_slot;
+       int stack_usage, map_count;
+       /* If not -1, then make a virtual call using this vtable offset */
+       int vcall_offset;
+       /* If 1, make an indirect call to the address in the rgctx reg */
+       int calli;
+       /* Whenever this is a in or an out call */
+       int gsharedvt_in;
+       /* Maps stack slots/registers in the caller to the stack slots/registers in the callee */
+       int map [MONO_ZERO_LEN_ARRAY];
 } GSharedVtCallInfo;
 
 /* Structure used by the sequence points in AOTed code */
@@ -233,8 +260,54 @@ typedef struct {
        mgreg_t regs [PARAM_REGS];
        mgreg_t res;
        guint8 *ret;
+       double fregs [8];
+       mgreg_t has_fp;
+       guint8 buffer [256];
 } DynCallArgs;
 
+typedef enum {
+       ArgInIReg,
+       ArgInFloatSSEReg,
+       ArgInDoubleSSEReg,
+       ArgOnStack,
+       ArgValuetypeInReg,
+       ArgValuetypeAddrInIReg,
+       /* gsharedvt argument passed by addr */
+       ArgGSharedVtInReg,
+       ArgGSharedVtOnStack,
+       ArgNone /* only in pair_storage */
+} ArgStorage;
+
+typedef struct {
+       gint16 offset;
+       gint8  reg;
+       ArgStorage storage : 8;
+       gboolean is_gsharedvt_return_value : 1;
+
+       /* Only if storage == ArgValuetypeInReg */
+       ArgStorage pair_storage [2];
+       gint8 pair_regs [2];
+       /* The size of each pair (bytes) */
+       int pair_size [2];
+       int nregs;
+       /* Only if storage == ArgOnStack */
+       int arg_size; // Bytes, will always be rounded up/aligned to 8 byte boundary
+} ArgInfo;
+
+typedef struct {
+       int nargs;
+       guint32 stack_usage;
+       guint32 reg_usage;
+       guint32 freg_usage;
+       gboolean need_stack_align;
+       /* The index of the vret arg in the argument list */
+       int vret_arg_index;
+       ArgInfo ret;
+       ArgInfo sig_cookie;
+       ArgInfo args [1];
+} CallInfo;
+
+
 #define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->gregs [AMD64_RAX] = (gsize)exc; } while (0)
 #define MONO_CONTEXT_SET_LLVM_EH_SELECTOR_REG(ctx, sel) do { (ctx)->gregs [AMD64_RDX] = (gsize)(sel); } while (0)
 
@@ -341,7 +414,6 @@ typedef struct {
 #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_HAVE_HANDLER_BLOCK_GUARD 1
 #define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER 1
@@ -357,10 +429,24 @@ typedef struct {
 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
 
+#if defined(TARGET_OSX) || defined(__linux__)
+#define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
+#endif
+
 #if defined(TARGET_OSX) || defined(__linux__)
 #define MONO_ARCH_HAVE_TLS_GET_REG 1
 #endif
 
+#if !defined (TARGET_WIN32)
+#define MONO_ARCH_GSHAREDVT_SUPPORTED 1
+#endif
+
+
+#if defined(TARGET_APPLETVOS)
+/* No signals */
+#define MONO_ARCH_NEED_DIV_CHECK 1
+#endif
+
 /* Used for optimization, not complete */
 #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE)
 
@@ -392,6 +478,9 @@ mono_amd64_resume_unwind (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint6
                                                  guint64 dummy5, guint64 dummy6,
                                                  MonoContext *mctx, guint32 dummy7, gint64 dummy8);
 
+gpointer
+mono_amd64_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg);
+
 guint64
 mono_amd64_get_original_ip (void);
 
@@ -418,5 +507,7 @@ void mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code,
 #define MONO_ARCH_HAVE_UNWIND_TABLE 1
 #endif
 
+CallInfo* mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig);
+
 #endif /* __MONO_MINI_AMD64_H__ */