Add OP_LREM_IMM support;Add implementation of mono_arch_get_delegate_virtual_invoke_impl
authorNeale Ferguson <neale@sinenomine.net>
Tue, 28 Oct 2014 18:48:45 +0000 (14:48 -0400)
committerNeale Ferguson <neale@sinenomine.net>
Tue, 28 Oct 2014 18:48:45 +0000 (14:48 -0400)
mono/mini/cpu-s390x.md
mono/mini/decompose.c
mono/mini/mini-s390x.c
mono/mini/support-s390x.h

index b3dce352ec640faff6fbb71abd21c2aeaab6042c..2eee2e4e57de2513cea47bc74092da93ed3c6aa0 100644 (file)
@@ -283,6 +283,7 @@ long_xor: dest:i src1:i src2:i len:8
 long_neg: dest:i src1:i len:6
 long_not: dest:i src1:i len:12
 long_rem: dest:i src1:i src2:i len:12
+long_rem_imm: dest:i src1:i src2:i len:12
 long_rem_un: dest:i src1:i src2:i len:16
 long_shl: dest:i src1:i src2:i len:14
 long_shl_imm: dest:i src1:i len:14
index 6e9d4aaef7190601aab7461fa11b92e62e521008..f29e913acf91e5849479f9e12d74514ffa68c1df 100644 (file)
@@ -486,6 +486,9 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
                        ins->opcode = OP_ICONST;
                        MONO_INST_NULLIFY_SREGS (ins);
                        ins->inst_c0 = 0;
+#if __s390__
+               }
+#else
                } else if ((ins->inst_imm > 0) && (ins->inst_imm < (1LL << 32)) && (power != -1)) {
                        gboolean is_long = ins->opcode == OP_LREM_IMM;
                        int compensator_reg = alloc_ireg (cfg);
@@ -511,6 +514,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
 
                        NULLIFY_INS (ins);
                }
+#endif
                break;
        }
 
index 435ef2904a495ce910dd6a9aa36e55ea1d9db6f7..d84c87860d1f95b652405201c0823ed719a62097 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);
@@ -3312,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);
@@ -5735,9 +5747,35 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 /*------------------------------------------------------------------*/
 
 gpointer
-mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
+mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, 
+                                           int offset, gboolean load_imt_reg)
 {
-       return NULL;
+       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 ========================*/
@@ -5833,7 +5871,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);
@@ -5863,7 +5901,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);
                        }
@@ -5932,7 +5970,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);
 }
index 62edcc4e7e9279bb91bdb4079c45b25be997a27f..f93dc88c0c6922e3b097ffd2c0f488df657801d9 100644 (file)
@@ -4,8 +4,12 @@
 #define S390_SET(loc, dr, v)                                   \
        do {                                                    \
                guint64 val = (guint64) v;                      \
-               if (s390_is_uimm16(val)) {                      \
+               if (s390_is_imm16(val)) {                       \
+                       s390_lghi(loc, dr, val);                \
+               } else if (s390_is_uimm16(val)) {               \
                        s390_llill(loc, dr, val);               \
+               } else if (s390_is_imm32(val)) {                \
+                       s390_lgfi(loc, dr, val);                \
                } else if (s390_is_uimm32(val)) {               \
                        s390_llilf(loc, dr, val);               \
                } else {                                        \