[jit] Expose helper method to the rest of the JIT to get specific trampoline descript...
[mono.git] / mono / mini / mini-s390x.c
index fbc6278a34239e379a26c97c0751bcfa055b63ed..a1618c932ebf84d95e0989029c0a4cdac80b0637 100644 (file)
@@ -246,8 +246,8 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #define JUMP_SIZE      6
 #define ENABLE_WRONG_METHOD_CHECK 0
 
-#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
-#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
+#define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex)
+#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
 
 /*========================= End of Defines =========================*/
 
@@ -260,6 +260,7 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <mono/metadata/abi-details.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/profiler-private.h>
@@ -409,7 +410,7 @@ static gpointer bp_trigger_page;
 
 breakpoint_t breakpointCode;
 
-static CRITICAL_SECTION mini_arch_mutex;
+static mono_mutex_t mini_arch_mutex;
 
 /*====================== End of Global Variables ===================*/
 
@@ -623,7 +624,7 @@ indent (int diff) {
        if (diff < 0)
                indent_level += diff;
        v = indent_level;
-       printf("%p [%3d] ",pthread_self(),v);
+       printf("%p [%3d] ",(void *)pthread_self(),v);
        while (v-- > 0) {
                printf (". ");
        }
@@ -1259,7 +1260,7 @@ mono_arch_init (void)
 {
        guint8 *code;
 
-       InitializeCriticalSection (&mini_arch_mutex);
+       mono_mutex_init_recursive (&mini_arch_mutex);
 
        ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
        bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
@@ -1290,7 +1291,7 @@ mono_arch_cleanup (void)
                mono_vfree (ss_trigger_page, mono_pagesize ());
        if (bp_trigger_page)
                mono_vfree (bp_trigger_page, mono_pagesize ());
-       DeleteCriticalSection (&mini_arch_mutex);
+       mono_mutex_destroy (&mini_arch_mutex);
 }
 
 /*========================= End of Function ========================*/
@@ -2797,6 +2798,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_IREM_UN_IMM:
                case OP_LAND_IMM:
                case OP_LOR_IMM:
+               case OP_LREM_IMM:
                case OP_LXOR_IMM:
                case OP_LOCALLOC_IMM:
                        mono_decompose_op_imm (cfg, bb, ins);
@@ -3311,6 +3313,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lgr  (code, ins->dreg, s390_r0);
                        break;
                }
+               case OP_LREM_IMM: {
+                       if (s390_is_imm16 (ins->inst_imm)) {
+                               s390_lghi (code, s390_r13, ins->inst_imm);
+                       } else {
+                               s390_lgfi (code, s390_r13, ins->inst_imm);
+                       }
+                       s390_lgr  (code, s390_r0, ins->sreg1);
+                       s390_dsgr (code, s390_r0, s390_r13);
+                       s390_lgfr (code, ins->dreg, s390_r0);
+               }
+                       break;
                case OP_LREM_UN: {
                        s390_lgr   (code, s390_r1, ins->sreg1);
                        s390_lghi  (code, s390_r0, 0);
@@ -4059,6 +4072,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_NOT_NULL: {
                }
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        int i;
 
@@ -4529,15 +4545,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lgr (code, ins->dreg, s390_r1);
                }
                        break;  
-               case OP_ATOMIC_ADD_NEW_I8: {
-                       s390_lgr (code, s390_r1, ins->sreg2);
-                       s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_agr (code, s390_r1, s390_r0);
-                       s390_csg (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -10);
-                       s390_lgr (code, ins->dreg, s390_r1);
-               }
-                       break;  
                case OP_ATOMIC_EXCHANGE_I8: {
                        s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
                        s390_csg (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
@@ -4554,15 +4561,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lgfr(code, ins->dreg, s390_r1);
                }
                        break;  
-               case OP_ATOMIC_ADD_NEW_I4: {
-                       s390_lgfr(code, s390_r1, ins->sreg2);
-                       s390_lgf (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_agr (code, s390_r1, s390_r0);
-                       s390_cs  (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -9);
-                       s390_lgfr(code, ins->dreg, s390_r1);
-               }
-                       break;  
                case OP_ATOMIC_EXCHANGE_I4: {
                        s390_l   (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
                        s390_cs  (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
@@ -5616,8 +5614,8 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                start = code = mono_global_codeman_reserve (size);
 
                /* Replace the this argument with the target */
-               s390_lg   (code, s390_r1, 0, s390_r2, G_STRUCT_OFFSET(MonoDelegate, method_ptr));
-               s390_lg   (code, s390_r2, 0, s390_r2, G_STRUCT_OFFSET(MonoDelegate, target));
+               s390_lg   (code, s390_r1, 0, s390_r2, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
+               s390_lg   (code, s390_r2, 0, s390_r2, MONO_STRUCT_OFFSET (MonoDelegate, target));
                s390_br   (code, s390_r1);
                g_assert ((code - start) <= size);
 
@@ -5628,7 +5626,7 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                size = 32 + param_count * 8;
                start = code = mono_global_codeman_reserve (size);
 
-               s390_lg   (code, s390_r1, 0, s390_r2, G_STRUCT_OFFSET(MonoDelegate, method_ptr));
+               s390_lg   (code, s390_r1, 0, s390_r2, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
                /* slide down the arguments */
                for (i = 0; i < param_count; ++i) {
                        s390_lgr (code, (s390_r2 + i), (s390_r2 + i + 1));
@@ -5743,6 +5741,48 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_get_delegate_virtual_invoke_impl.       */
+/*                                                                  */
+/* Function    -                                                   */
+/*                                                                 */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, 
+                                           int offset, gboolean load_imt_reg)
+{
+       guint8 *code, *start;
+       int size = 20;
+
+       start = code = mono_global_codeman_reserve (size);
+
+       /*
+        * Replace the "this" argument with the target
+        */
+       s390_lgr  (code, s390_r1, s390_r2);
+       s390_lg   (code, s390_r2, s390_r1, 0, MONO_STRUCT_OFFSET(MonoDelegate, target));        
+       
+       /*
+        * Load the IMT register, if needed
+        */
+       if (load_imt_reg) {
+               s390_lg  (code, MONO_ARCH_IMT_REG, s390_r2, 0, MONO_STRUCT_OFFSET(MonoDelegate, method));
+       }
+
+       /*
+        * Load the vTable
+        */
+       s390_lg  (code, s390_r1, s390_r2, 0, MONO_STRUCT_OFFSET(MonoObject, vtable));
+       s390_agfi(code, s390_r1, offset);
+       s390_br  (code, s390_r1);
+
+       return(start);
+}
+
+/*========================= End of Function ========================*/
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_build_imt_thunk.                        */
@@ -5834,7 +5874,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
                                                s390_lg   (code, s390_r1, 0, s390_r1, 0);
                                        }
                                        s390_br   (code, s390_r1);
-                                       target = S390_RELATIVE(code, item->jmp_code);
+                                       target = (gint64) S390_RELATIVE(code, item->jmp_code);
                                        s390_patch_rel(item->jmp_code+2, target);
                                        S390_SET  (code, s390_r1, fail_tramp);
                                        s390_br   (code, s390_r1);
@@ -5864,7 +5904,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
                if (item->jmp_code) {
                        if (item->check_target_idx) {
                                gint64 offset;
-                               offset = S390_RELATIVE(imt_entries [item->check_target_idx]->code_target,
+                               offset = (gint64) S390_RELATIVE(imt_entries [item->check_target_idx]->code_target,
                                                       item->jmp_code);
                                s390_patch_rel ((guchar *) item->jmp_code + 2, (guint64) offset);
                        }
@@ -5933,7 +5973,7 @@ mono_arch_get_cie_program (void)
 {
        GSList *l = NULL;
 
-       mono_add_unwind_op_def_cfa (l, NULL, NULL, STK_BASE, 0);
+       mono_add_unwind_op_def_cfa (l, 0, 0, STK_BASE, 0);
 
        return(l);
 }
@@ -6138,3 +6178,17 @@ mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
 /*========================= End of Function ========================*/
 
 #endif
+
+gboolean
+mono_arch_opcode_supported (int opcode)
+{
+       switch (opcode) {
+       case OP_ATOMIC_ADD_I4:
+       case OP_ATOMIC_ADD_I8:
+       case OP_ATOMIC_EXCHANGE_I4:
+       case OP_ATOMIC_EXCHANGE_I8:
+               return TRUE;
+       default:
+               return FALSE;
+       }
+}