2009-12-30 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / mini / mini-ia64.c
index c44af5c899bbd5756f67215ca88601901b26cbcb..a61142d7eb526190312e2d3c9d6e9cc0f1b8e22b 100644 (file)
@@ -401,7 +401,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo
                        cinfo->ret.reg = 8;
                        break;
                case MONO_TYPE_GENERICINST:
-                       if (!mono_type_generic_inst_is_valuetype (sig->ret)) {
+                       if (!mono_type_generic_inst_is_valuetype (ret_type)) {
                                cinfo->ret.storage = ArgInIReg;
                                cinfo->ret.reg = IA64_R8;
                                break;
@@ -494,7 +494,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo
                        add_general (&gr, &stack_size, ainfo);
                        break;
                case MONO_TYPE_GENERICINST:
-                       if (!mono_type_generic_inst_is_valuetype (sig->params [i])) {
+                       if (!mono_type_generic_inst_is_valuetype (ptype)) {
                                add_general (&gr, &stack_size, ainfo);
                                break;
                        }
@@ -2128,6 +2128,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ia64_shl (code, ins->dreg, ins->sreg1, ins->sreg2);
                        break;
                case OP_ISHR:
+                       ia64_sxt4 (code, GP_SCRATCH_REG, ins->sreg1);
+                       ia64_shr (code, ins->dreg, GP_SCRATCH_REG, ins->sreg2);
+                       break;
                case OP_LSHR:
                        ia64_shr (code, ins->dreg, ins->sreg1, ins->sreg2);
                        break;
@@ -2227,10 +2230,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ia64_shl_imm (code, ins->dreg, ins->sreg1, ins->inst_imm);
                        break;
                case OP_SHR_IMM:
-               case OP_ISHR_IMM:
                case OP_LSHR_IMM:
                        ia64_shr_imm (code, ins->dreg, ins->sreg1, ins->inst_imm);
                        break;
+               case OP_ISHR_IMM:
+                       g_assert (ins->inst_imm <= 64);
+                       ia64_extr (code, ins->dreg, ins->sreg1, ins->inst_imm, 32 - ins->inst_imm);
+                       break;
                case OP_ISHR_UN_IMM:
                        ia64_zxt4 (code, GP_SCRATCH_REG, ins->sreg1);
                        ia64_shr_u_imm (code, ins->dreg, GP_SCRATCH_REG, ins->inst_imm);
@@ -4551,7 +4557,7 @@ mono_arch_get_vcall_slot (guint8* code, mgreg_t *regs, int *displacement)
 
                *displacement = (gssize)regs [IA64_R8] - (gssize)regs [IA64_R11];
 
-               return regs [IA64_R11];
+               return (gpointer)regs [IA64_R11];
        }
 
        return NULL;
@@ -4589,8 +4595,6 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        guint8 *start, *buf;
        Ia64CodegenState code;
 
-       g_assert (!fail_tramp);
-
        size = count * 256;
        buf = g_malloc0 (size);
        ia64_codegen_init (code, buf);
@@ -4602,8 +4606,10 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                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) {
+                       gboolean fail_case = !item->check_target_idx && fail_tramp;
+
+                       if (item->check_target_idx || fail_case) {
+                               if (!item->compare_done || fail_case) {
                                        ia64_movl (code, GP_SCRATCH_REG, item->key);
                                        ia64_cmp_eq (code, 6, 7, IA64_R9, GP_SCRATCH_REG);
                                }
@@ -4614,6 +4620,15 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                ia64_ld8 (code, GP_SCRATCH_REG, GP_SCRATCH_REG);
                                ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG);
                                ia64_br_cond_reg (code, IA64_B6);
+
+                               if (fail_case) {
+                                       ia64_patch (item->jmp_code, (guint8*)code.buf + code.nins);
+                                       ia64_movl (code, GP_SCRATCH_REG, fail_tramp);
+                                       ia64_ld8 (code, GP_SCRATCH_REG, GP_SCRATCH_REG);
+                                       ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG);
+                                       ia64_br_cond_reg (code, IA64_B6);
+                                       item->jmp_code = NULL;
+                               }
                        } else {
                                /* enable the commented code to assert on wrong method */
 #if ENABLE_WRONG_METHOD_CHECK
@@ -4648,7 +4663,12 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        g_assert (code.buf - buf <= size);
 
        size = code.buf - buf;
-       start = mono_domain_code_reserve (domain, size);
+       if (fail_tramp) {
+               start = mono_method_alloc_generic_virtual_thunk (domain, size + 16);
+               start = (gpointer)ALIGN_TO (start, 16);
+       } else {
+               start = mono_domain_code_reserve (domain, size);
+       }
        memcpy (start, buf, size);
 
        mono_arch_flush_icache (start, size);
@@ -4661,7 +4681,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 MonoMethod*
 mono_arch_find_imt_method (mgreg_t *regs, guint8 *code)
 {
-       return regs [IA64_R9];
+       return (MonoMethod*)regs [IA64_R9];
 }
 
 void
@@ -4677,12 +4697,6 @@ mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSi
        return (gpointer)regs [IA64_R10];
 }
 
-MonoObject*
-mono_arch_find_this_argument (mgreg_t *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
-{
-       return mono_arch_get_this_arg_from_call (gsctx, mono_method_signature (method), regs, NULL);
-}
-
 gpointer
 mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
 {
@@ -4791,12 +4805,6 @@ mono_arch_get_domain_intrinsic (MonoCompile* cfg)
        return mono_get_domain_intrinsic (cfg);
 }
 
-MonoInst*
-mono_arch_get_thread_intrinsic (MonoCompile* cfg)
-{
-       return mono_get_thread_intrinsic (cfg);
-}
-
 gpointer
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {