s390x-codegen.h : Fix instruction definition and add instruction format variant
[mono.git] / mono / mini / mini-s390x.c
index 0318e12c53683725440bb1ff4e34c7d9be09e551..004540fb7e2bc7bbf8790e10411aee7e0a852a2d 100644 (file)
@@ -624,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 (". ");
        }
@@ -2798,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);
@@ -2925,24 +2926,20 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        guint offset;
        guint8 *code = cfg->native_code + cfg->code_len;
        guint last_offset = 0;
-       int max_len, cpos, src2;
+       int max_len, src2;
 
        /* we don't align basic blocks of loops on s390 */
 
        if (cfg->verbose_level > 2)
                g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset);
 
-       cpos = bb->max_offset;
-
-       if (cfg->prof_options & MONO_PROFILE_COVERAGE) {
-               //MonoCoverageInfo *cov = mono_get_coverage_info (cfg->method);
-               //g_assert (!mono_compile_aot);
-               //cpos += 6;
-               //if (bb->cil_code)
-               //      cov->data [bb->dfn].iloffset = bb->cil_code - cfg->cil_code;
-               /* this is not thread save, but good enough */
-               /* fixme: howto handle overflows? */
-               //x86_inc_mem (code, &cov->data [bb->dfn].count); 
+       if ((cfg->prof_options & MONO_PROFILE_COVERAGE) && cfg->coverage_info) {
+               MonoProfileCoverageInfo *cov = cfg->coverage_info;
+               g_assert (!mono_compile_aot);
+               cov->data [bb->dfn].cil_code = bb->cil_code;
+               /* This is not thread save, but good enough */
+               S390_SET (code, s390_r1, &cov->data [bb->dfn].count);
+               s390_alsi (code, 0, s390_r1, 1);
        }
 
        MONO_BB_FOR_EACH_INS (bb, ins) {
@@ -3312,6 +3309,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);
@@ -3815,20 +3823,30 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, "OverflowException");
                        s390_lgfr (code, ins->dreg, ins->sreg1);
                        break;
-               case OP_FMOVE: {
+               case OP_FMOVE:
                        if (ins->dreg != ins->sreg1) {
                                s390_ldr   (code, ins->dreg, ins->sreg1);
                        }
-               }
                        break;
-               case OP_FCONV_TO_R4: {
+               case OP_MOVE_F_TO_I8: 
+                       s390_lgdr (code, ins->dreg, ins->sreg1);
+                       break;
+               case OP_MOVE_I8_TO_F: 
+                       s390_ldgr (code, ins->dreg, ins->sreg1);
+                       break;
+               case OP_MOVE_F_TO_I4:
+                       s390_lgdr (code, ins->dreg, ins->sreg1);
+                       break;
+               case OP_MOVE_I4_TO_F: 
+                       s390_lgfr (code, s390_r0, ins->sreg1);
+                       s390_ldgr (code, ins->dreg, s390_r0);
+                       break;
+               case OP_FCONV_TO_R4:
                        s390_ledbr (code, ins->dreg, ins->sreg1);
                        s390_ldebr (code, ins->dreg, ins->dreg);
-               }
                        break;
-               case OP_S390_SETF4RET: {
+               case OP_S390_SETF4RET:
                        s390_ledbr (code, ins->dreg, ins->sreg1);
-               }
                        break;
                case OP_TLS_GET: {
                        if (s390_is_imm16 (ins->inst_offset)) {
@@ -4060,6 +4078,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;
 
@@ -4565,8 +4586,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;  
-               case OP_MEMORY_BARRIER: {
-               }
+               case OP_MEMORY_BARRIER:
+                       s390_mem (code);
                        break;
                case OP_GC_LIVENESS_DEF:
                case OP_GC_LIVENESS_USE:
@@ -4588,8 +4609,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_assert_not_reached ();
                }
               
-               cpos += max_len;
-
                last_offset = offset;
        }
 
@@ -5623,6 +5642,8 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                mono_arch_flush_icache (start, size);
        }
 
+       mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
+
        if (code_len)
                *code_len = code - start;
 
@@ -5726,6 +5747,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.                        */
@@ -5817,7 +5880,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);
@@ -5847,7 +5910,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);
                        }
@@ -5855,8 +5918,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
        }
 
        mono_arch_flush_icache ((guint8*)start, (code - start));
+       mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
 
-       if (!fail_tramp)
+       if (!fail_tramp) 
                mono_stats.imt_thunks_size += (code - start);
 
        g_assert (code - start <= size);
@@ -5916,7 +5980,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);
 }