Author: zoltan
Date: 2007-10-17 14:56:35 -0400 (Wed, 17 Oct 2007)
New Revision: 87704

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/inssel.brg
   trunk/mono/mono/mini/mini-ia64.c
   trunk/mono/mono/mini/mini-ia64.h
Log:
2007-10-17  Zoltan Varga  <[EMAIL PROTECTED]>

        * inssel.brg (mini_emit_virtual_call): Fix the computation of 
ins->inst_offset on
        64 bit platforms.

        * mini-ia64.h mini-ia64.c: Add support for IMT.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/ChangeLog      2007-10-17 18:56:35 UTC (rev 87704)
@@ -1,5 +1,10 @@
 2007-10-17  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * inssel.brg (mini_emit_virtual_call): Fix the computation of 
ins->inst_offset on
+       64 bit platforms.
+
+       * mini-ia64.h mini-ia64.c: Add support for IMT.
+
        * mini-x86.c (mono_arch_emit_prolog): Increase the size allocated for 
the
        prolog. Fixes #331958.
 

Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg     2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/inssel.brg     2007-10-17 18:56:35 UTC (rev 87704)
@@ -1814,7 +1814,7 @@
                guint32 imt_slot = mono_method_get_imt_slot (method);
                emit_imt_argument (cfg, (MonoCallInst*)tree);
                slot_reg = vtable_reg;
-               tree->inst_offset = (imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
+               tree->inst_offset = ((gint32)imt_slot - MONO_IMT_SIZE) * 
SIZEOF_VOID_P;
 #else
                slot_reg = mono_regstate_next_int (cfg->rs);
                mini_emit_load_intf_reg_vtable (cfg, slot_reg, vtable_reg, 
method->klass);

Modified: trunk/mono/mono/mini/mini-ia64.c
===================================================================
--- trunk/mono/mono/mini/mini-ia64.c    2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/mini-ia64.c    2007-10-17 18:56:35 UTC (rev 87704)
@@ -2803,7 +2803,11 @@
                case OP_LCALL_MEMBASE:
                case OP_VCALL_MEMBASE:
                case OP_VOIDCALL_MEMBASE:
-               case OP_CALL_MEMBASE:
+               case OP_CALL_MEMBASE: {
+                       MonoCallInst *call = (MonoCallInst*)ins;
+                       CallInfo *cinfo;
+                       int out_reg;
+
                        /* 
                         * There are no membase instructions on ia64, but we 
can't 
                         * lower this since get_vcall_slot_addr () needs to 
decode it.
@@ -2817,6 +2821,26 @@
                                ia64_add (code, IA64_R8, GP_SCRATCH_REG, 
ins->sreg1);
                        }
 
+                       if (call->method && ins->inst_offset < 0) {
+                               /* 
+                                * This is a possible IMT call so save the IMT 
method in a global 
+                                * register where mono_arch_find_imt_method () 
and its friends can access 
+                                * it.
+                                */
+                               ia64_movl (code, IA64_R9, call->method);
+                       }
+
+                       /* 
+                        * mono_arch_find_this_arg () needs to find the this 
argument in a global 
+                        * register.
+                        */
+                       cinfo = get_call_info (NULL, call->signature, FALSE);
+                       out_reg = cfg->arch.reg_out0;
+                       if (cinfo->ret.storage == ArgValuetypeAddrInIReg)
+                               out_reg ++;
+                       g_free (cinfo);
+                       ia64_mov (code, IA64_R10, out_reg);
+
                        ia64_begin_bundle (code);
                        ia64_codegen_set_one_ins_per_bundle (code, TRUE);
 
@@ -2836,6 +2860,7 @@
 
                        code = emit_move_return_value (cfg, ins, code);
                        break;
+               }
                case OP_JMP: {
                        /*
                         * Keep in sync with the code in emit_epilog.
@@ -4608,6 +4633,104 @@
        }
 }
 
+
+#ifdef MONO_ARCH_HAVE_IMT
+
+/*
+ * LOCKING: called with the domain lock held
+ */
+gpointer
+mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, 
MonoIMTCheckItem **imt_entries, int count)
+{
+       int i;
+       int size = 0;
+       guint8 *start, *buf;
+       Ia64CodegenState code;
+
+       size = count * 256;
+       buf = g_malloc0 (size);
+       ia64_codegen_init (code, buf);
+
+       for (i = 0; i < count; ++i) {
+               MonoIMTCheckItem *item = imt_entries [i];
+               ia64_begin_bundle (code);
+               item->code_target = (guint8*)code.buf + code.nins;
+               if (item->is_equals) {
+                       if (item->check_target_idx) {
+                               if (!item->compare_done) {
+                                       ia64_movl (code, IA64_R8, item->method);
+                                       ia64_cmp_eq (code, 6, 7, IA64_R9, 
IA64_R8);
+                               }
+                               item->jmp_code = (guint8*)code.buf + code.nins;
+                               ia64_br_cond_pred (code, 7, 0);
+
+                               ia64_movl (code, IA64_R8, &(vtable->vtable 
[item->vtable_slot]));
+                               ia64_ld8 (code, IA64_R8, IA64_R8);
+                               ia64_mov_to_br (code, IA64_B6, IA64_R8);
+                               ia64_br_cond_reg (code, IA64_B6);
+                       } else {
+                               /* enable the commented code to assert on wrong 
method */
+#if ENABLE_WRONG_METHOD_CHECK
+                               g_assert_not_reached ();
+#endif
+                               ia64_movl (code, IA64_R8, &(vtable->vtable 
[item->vtable_slot]));
+                               ia64_ld8 (code, IA64_R8, IA64_R8);
+                               ia64_mov_to_br (code, IA64_B6, IA64_R8);
+                               ia64_br_cond_reg (code, IA64_B6);
+#if ENABLE_WRONG_METHOD_CHECK
+                               g_assert_not_reached ();
+#endif
+                       }
+               } else {
+                       ia64_movl (code, IA64_R8, item->method);
+                       ia64_cmp_geu (code, 6, 7, IA64_R9, IA64_R8);
+                       item->jmp_code = (guint8*)code.buf + code.nins;
+                       ia64_br_cond_pred (code, 6, 0);
+               }
+       }
+       /* patch the branches to get to the target items */
+       for (i = 0; i < count; ++i) {
+               MonoIMTCheckItem *item = imt_entries [i];
+               if (item->jmp_code) {
+                       if (item->check_target_idx) {
+                               ia64_patch (item->jmp_code, imt_entries 
[item->check_target_idx]->code_target);
+                       }
+               }
+       }
+
+       ia64_codegen_close (code);
+       g_assert (code.buf - buf <= size);
+
+       size = code.buf - buf;
+       start = mono_code_manager_reserve (domain->code_mp, size);
+       memcpy (start, buf, size);
+
+       mono_arch_flush_icache (start, size);
+
+       mono_stats.imt_thunks_size += size;
+
+       return start;
+}
+
+MonoMethod*
+mono_arch_find_imt_method (gpointer *regs, guint8 *code)
+{
+       return regs [IA64_R9];
+}
+
+MonoObject*
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+{
+       return regs [IA64_R10];
+}
+
+void
+mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call)
+{
+       /* Done by the implementation of the CALL_MEMBASE opcodes */
+}
+#endif
+
 MonoInst*
 mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, 
MonoMethodSignature *fsig, MonoInst **args)
 {

Modified: trunk/mono/mono/mini/mini-ia64.h
===================================================================
--- trunk/mono/mono/mini/mini-ia64.h    2007-10-17 17:16:59 UTC (rev 87703)
+++ trunk/mono/mono/mini/mini-ia64.h    2007-10-17 18:56:35 UTC (rev 87704)
@@ -183,5 +183,6 @@
 #define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1
 #define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1
 #define MONO_ARCH_HAVE_CREATE_VARS 1
+#define MONO_ARCH_HAVE_IMT 1
 
 #endif /* __MONO_MINI_IA64_H__ */  

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to