2009-11-24 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Tue, 24 Nov 2009 21:58:20 +0000 (21:58 -0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 24 Nov 2009 21:58:20 +0000 (21:58 -0000)
* tramp-arm.c: Use blx instead of mov pc, reg to improve support for thumb.

* mini-arm.c (mono_arm_thumb_supported): New helper function.

svn path=/trunk/mono/; revision=146863

mono/mini/ChangeLog
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/tramp-arm.c

index 6aa4f526333357ab446fa8434b7e35b4ce0b1dce..7f763d8cd601699130545e6538dc112a7e7223f8 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-24  Zoltan Varga  <vargaz@gmail.com>
+
+       * tramp-arm.c: Use blx instead of mov pc, reg to improve support for thumb.
+
+       * mini-arm.c (mono_arm_thumb_supported): New helper function.
+
 2009-11-24  Zoltan Varga  <vargaz@gmail.com>
 
        * cfold.c (mono_constant_fold_ins): Fix a problem in the previous change,
index 84f781d0df5a635eca28ec6e75e4f5ce34252d57..715bbe5ee5af641dceedfe22c6a71f03000fc2bb 100644 (file)
@@ -2896,6 +2896,12 @@ mono_arm_emit_load_imm (guint8 *code, int dreg, guint32 val)
        return code;
 }
 
+gboolean
+mono_arm_thumb_supported (void)
+{
+       return thumb_supported;
+}
+
 /*
  * emit_load_volatile_arguments:
  *
index a0ff553f76c622aa4e53befb436fe95479855b31..ef5c8337ad74c48547aea6823ff0969e77e46191 100644 (file)
@@ -211,5 +211,8 @@ mono_arm_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp,
 void
 mono_arm_throw_exception_by_token (guint32 type_token, unsigned long eip, unsigned long esp, gulong *int_regs, gdouble *fp_regs);
 
+gboolean
+mono_arm_thumb_supported (void);
+
 #endif /* __MONO_MINI_ARM_H__ */
 
index b779b44f9284e8957e3625f8d3bcf1a963423e91..8924c88b29d178394f71f32cb5417d83a99529f1 100644 (file)
@@ -40,6 +40,16 @@ branch_for_target_reachable (guint8 *branch, guint8 *target)
        return 0;
 }
 
+static inline guint8*
+emit_bx (guint8* code, int reg)
+{
+       if (mono_arm_thumb_supported ())
+               ARM_BX (code, reg);
+       else
+               ARM_MOV_REG_REG (code, ARMREG_PC, reg);
+       return code;
+}
+
 /*
  * mono_arch_get_unbox_trampoline:
  * @gsctx: the generic sharing context
@@ -64,7 +74,7 @@ mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *m,
 
        ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 4);
        ARM_ADD_REG_IMM8 (code, this_pos, this_pos, sizeof (MonoObject));
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+       code = emit_bx (code, ARMREG_IP);
        *(guint32*)code = (guint32)addr;
        code += 4;
        mono_arch_flush_icache (start, code - start);
@@ -266,7 +276,7 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
                code += 4;
        }
        ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R0);
+       code = emit_bx (code, ARMREG_R0);
 
        /* we build the MonoLMF structure on the stack - see mini-arm.h
         * The pointer to the struct is put in r1.
@@ -331,7 +341,7 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
        }
 
        ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+       code = emit_bx (code, ARMREG_IP);
        
        /* OK, code address is now on r0. Move it to the place on the stack
         * where IP was saved (it is now no more useful to us and it can be
@@ -359,7 +369,7 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
                code += 4;
        }
        ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+       code = emit_bx (code, ARMREG_IP);
 
        /*
         * Now we restore the MonoLMF (see emit_epilogue in mini-arm.c)
@@ -388,9 +398,9 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
        /* do we need to set sp? */
        ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, (14 * 4));
        if ((tramp_type == MONO_TRAMPOLINE_CLASS_INIT) || (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT) || (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH))
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_LR);
+               code = emit_bx (code, ARMREG_LR);
        else
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+               code = emit_bx (code, ARMREG_IP);
 
        constants = (gpointer*)code;
        constants [0] = mono_get_lmf_addr;
@@ -431,7 +441,7 @@ mono_arch_get_nullified_class_init_trampoline (guint32 *code_len)
 
        code = buf = mono_global_codeman_reserve (16);
 
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_LR);
+       code = emit_bx (code, ARMREG_LR);
 
        mono_arch_flush_icache (buf, code - buf);
 
@@ -481,7 +491,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
        } else {
                ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 8); /* temp reg */
                ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
+               code = emit_bx (code, ARMREG_R1);
 
                constants = (gpointer*)code;
                constants [0] = arg1;
@@ -586,7 +596,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
        ARM_B_COND (code, ARMCOND_EQ, 0);
        /* otherwise return, result is in R1 */
        ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_R1);
-       ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_LR);
+       code = emit_bx (code, ARMREG_LR);
 
        g_assert (njumps <= depth + 2);
        for (i = 0; i < njumps; ++i)
@@ -610,7 +620,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
 
                /* Jump to the actual trampoline */
                ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
+               code = emit_bx (code, ARMREG_R1);
                *(gpointer*)code = tramp;
                code += 4;
        }
@@ -683,7 +693,7 @@ mono_arch_create_generic_class_init_trampoline_full (guint32 *code_size, MonoJum
 
                /* Jump to the actual trampoline */
                ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
+               code = emit_bx (code, ARMREG_R1);
                *(gpointer*)code = tramp;
                code += 4;
        }