Merge pull request #2998 from lateralusX/jlorenss/win-x64-full-aot-support
[mono.git] / mono / mini / mini-amd64.h
index 526e5b00c195d3652e55a35ef1766472b3ed90b5..33c815d75762d6a97121fb703e0660b844fa6c2d 100644 (file)
@@ -6,26 +6,6 @@
 #include <mono/utils/mono-context.h>
 #include <glib.h>
 
-#ifdef __native_client_codegen__
-#define kNaClAlignmentAMD64 32
-#define kNaClAlignmentMaskAMD64 (kNaClAlignmentAMD64 - 1)
-
-/* TODO: use kamd64NaClLengthOfCallImm    */
-/* temporarily using kNaClAlignmentAMD64 so padding in */
-/* image-writer.c doesn't happen                       */
-#define kNaClLengthOfCallImm kNaClAlignmentAMD64
-
-int is_nacl_call_reg_sequence (guint8* code);
-void amd64_nacl_clear_legacy_prefix_tag ();
-void amd64_nacl_tag_legacy_prefix (guint8* code);
-void amd64_nacl_tag_rex (guint8* code);
-guint8* amd64_nacl_get_legacy_prefix_tag ();
-guint8* amd64_nacl_get_rex_tag ();
-void amd64_nacl_instruction_pre ();
-void amd64_nacl_instruction_post (guint8 **start, guint8 **end);
-void amd64_nacl_membase_handler (guint8** code, gint8 basereg, gint32 offset, gint8 dreg);
-#endif
-
 #ifdef HOST_WIN32
 #include <windows.h>
 /* use SIG* defines if possible */
@@ -175,13 +155,7 @@ struct MonoLMF {
         * the 'rbp' field is not valid.
         */
        gpointer    previous_lmf;
-#if defined(__default_codegen__) || defined(HOST_WIN32)
        guint64     rip;
-#elif defined(__native_client_codegen__)
-       /* On 64-bit compilers, default alignment is 8 for this field, */
-       /* this allows the structure to match for 32-bit compilers.    */
-       guint64     rip __attribute__ ((aligned(8)));
-#endif
        guint64     rbp;
        guint64     rsp;
 };
@@ -215,12 +189,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,9 +234,56 @@ 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,
+       /* Variable sized gsharedvt argument passed/returned by addr */
+       ArgGsharedvtVariableInReg,
+       ArgNone /* only in pair_storage */
+} ArgStorage;
+
+typedef struct {
+       gint16 offset;
+       gint8  reg;
+       ArgStorage storage : 8;
+
+       /* 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;
+       gboolean gsharedvt;
+       /* 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)
 
@@ -275,7 +323,7 @@ typedef struct {
  */
 #define MONO_ARCH_VARARG_ICALLS 1
 
-#if (!defined( HOST_WIN32 ) && !defined(__native_client__) && !defined(__native_client_codegen__)) && defined (HAVE_SIGACTION)
+#if !defined( HOST_WIN32 ) && defined (HAVE_SIGACTION)
 
 #define MONO_ARCH_USE_SIGACTION 1
 
@@ -285,7 +333,7 @@ typedef struct {
 
 #endif
 
-#endif /* !HOST_WIN32 && !__native_client__ */
+#endif /* !HOST_WIN32 */
 
 #if !defined(__linux__)
 #define MONO_ARCH_NOMAP32BIT 1
@@ -332,9 +380,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
 
 #define MONO_ARCH_AOT_SUPPORTED 1
-#if !defined( __native_client__ )
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
-#endif
 
 #define MONO_ARCH_SUPPORT_TASKLETS 1
 
@@ -361,10 +407,15 @@ typedef struct {
 #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
 #endif
 
-#if defined(TARGET_OSX) || defined(__linux__)
+#if defined(TARGET_OSX) || defined(__linux__) || defined(TARGET_WIN32)
 #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
@@ -401,6 +452,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);
 
@@ -427,5 +481,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__ */