Merge pull request #2720 from mono/fix-39325
[mono.git] / mono / mini / mini-amd64.h
index fbea7e0de5d04a9c2d472713b4432bbd75c31ed1..c22c9be0fd0007b3969fc7beec42ac686e66e0d9 100644 (file)
@@ -215,8 +215,18 @@ 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 {
@@ -224,9 +234,10 @@ typedef struct {
        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 */
+       /* 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 */
+       /* 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 */
@@ -254,6 +265,49 @@ typedef struct {
        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)
 
@@ -368,7 +422,6 @@ typedef struct {
 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
 #define MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK 1
-#define MONO_ARCH_GSHAREDVT_SUPPORTED 1
 #define MONO_ARCH_HAVE_OP_TAIL_CALL 1
 #define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1
 #define MONO_ARCH_HAVE_DUMMY_INIT 1
@@ -384,6 +437,11 @@ typedef struct {
 #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
@@ -449,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__ */