New tests.
[mono.git] / mono / mini / mini-arm.c
index 3a8d1723d1b91011670810ce0a7dda4017e2210e..0a72637f062ad53b5efd0e90572c5925241fab7c 100644 (file)
@@ -136,6 +136,8 @@ mono_arch_fregname (int reg)
        return "unknown";
 }
 
+#ifndef DISABLE_JIT
+
 static guint8*
 emit_big_add (guint8 *code, int dreg, int sreg, int imm)
 {
@@ -247,6 +249,8 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
        return code;
 }
 
+#endif /* #ifndef DISABLE_JIT */
+
 /*
  * mono_arch_get_argument_info:
  * @csig:  a method signature
@@ -549,6 +553,14 @@ guint32
 mono_arch_cpu_optimizazions (guint32 *exclude_mask)
 {
        guint32 opts = 0;
+       const char *cpu_arch = getenv ("MONO_CPU_ARCH");
+       if (cpu_arch != NULL) {
+               thumb_supported = strstr (cpu_arch, "thumb") != NULL;
+               if (strncmp (cpu_arch, "armv", 4) == 0) {
+                       v5_supported = cpu_arch [4] >= '5';
+                       v7_supported = cpu_arch [4] >= '7';
+               }
+       } else {
 #if __APPLE__
        thumb_supported = TRUE;
        v5_supported = TRUE;
@@ -580,12 +592,15 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
                /*printf ("features: v5: %d, thumb: %d\n", v5_supported, thumb_supported);*/
        }
 #endif
+       }
 
        /* no arm-specific optimizations yet */
        *exclude_mask = 0;
        return opts;
 }
 
+#ifndef DISABLE_JIT
+
 static gboolean
 is_regsize_var (MonoType *t) {
        if (t->byref)
@@ -685,6 +700,8 @@ mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
        return 2;
 }
 
+#endif /* #ifndef DISABLE_JIT */
+
 #ifndef __GNUC_PREREQ
 #define __GNUC_PREREQ(maj, min) (0)
 #endif
@@ -1041,6 +1058,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
        return cinfo;
 }
 
+#ifndef DISABLE_JIT
 
 /*
  * Set var information according to the calling convention. arm version.
@@ -1051,7 +1069,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 {
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
-       MonoInst *inst;
+       MonoInst *ins;
        int i, offset, size, align, curinst;
        int frame_reg = ARMREG_FP;
        CallInfo *cinfo;
@@ -1070,7 +1088,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method))
                cfg->param_area = MAX (cfg->param_area, sizeof (gpointer)*8);
 
-       header = mono_method_get_header (cfg->method);
+       header = cfg->header;
 
        /* 
         * We use the frame register also for any method that has
@@ -1134,12 +1152,12 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                        offset &= ~(sizeof (gpointer) - 1);
                        cfg->ret->inst_offset = - offset;
                } else {
-                       inst = cfg->vret_addr;
+                       ins = cfg->vret_addr;
                        offset += sizeof(gpointer) - 1;
                        offset &= ~(sizeof(gpointer) - 1);
-                       inst->inst_offset = offset;
-                       inst->opcode = OP_REGOFFSET;
-                       inst->inst_basereg = frame_reg;
+                       ins->inst_offset = offset;
+                       ins->opcode = OP_REGOFFSET;
+                       ins->inst_basereg = frame_reg;
                        if (G_UNLIKELY (cfg->verbose_level > 1)) {
                                printf ("vret_addr =");
                                mono_print_ins (cfg->vret_addr);
@@ -1148,20 +1166,46 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                offset += sizeof(gpointer);
        }
 
+       /* Allocate these first so they have a small offset, OP_SEQ_POINT depends on this */
+       if (cfg->arch.seq_point_info_var) {
+               MonoInst *ins;
+
+               ins = cfg->arch.seq_point_info_var;
+
+               size = 4;
+               align = 4;
+               offset += align - 1;
+               offset &= ~(align - 1);
+               ins->opcode = OP_REGOFFSET;
+               ins->inst_basereg = frame_reg;
+               ins->inst_offset = offset;
+               offset += size;
+
+               ins = cfg->arch.ss_trigger_page_var;
+               size = 4;
+               align = 4;
+               offset += align - 1;
+               offset &= ~(align - 1);
+               ins->opcode = OP_REGOFFSET;
+               ins->inst_basereg = frame_reg;
+               ins->inst_offset = offset;
+               offset += size;
+       }
+
        curinst = cfg->locals_start;
        for (i = curinst; i < cfg->num_varinfo; ++i) {
-               inst = cfg->varinfo [i];
-               if ((inst->flags & MONO_INST_IS_DEAD) || inst->opcode == OP_REGVAR)
+               ins = cfg->varinfo [i];
+               if ((ins->flags & MONO_INST_IS_DEAD) || ins->opcode == OP_REGVAR || ins->opcode == OP_REGOFFSET)
                        continue;
 
                /* inst->backend.is_pinvoke indicates native sized value types, this is used by the
                * pinvoke wrappers when they call functions returning structure */
-               if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype) && inst->inst_vtype->type != MONO_TYPE_TYPEDBYREF) {
-                       size = mono_class_native_size (mono_class_from_mono_type (inst->inst_vtype), &ualign);
+               if (ins->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (ins->inst_vtype) && ins->inst_vtype->type != MONO_TYPE_TYPEDBYREF) {
+                       size = mono_class_native_size (mono_class_from_mono_type (ins->inst_vtype), &ualign);
                        align = ualign;
                }
                else
-                       size = mono_type_size (inst->inst_vtype, &align);
+                       size = mono_type_size (ins->inst_vtype, &align);
 
                /* FIXME: if a structure is misaligned, our memcpy doesn't work,
                 * since it loads/stores misaligned words, which don't do the right thing.
@@ -1170,22 +1214,22 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                        align = 4;
                offset += align - 1;
                offset &= ~(align - 1);
-               inst->inst_offset = offset;
-               inst->opcode = OP_REGOFFSET;
-               inst->inst_basereg = frame_reg;
+               ins->opcode = OP_REGOFFSET;
+               ins->inst_offset = offset;
+               ins->inst_basereg = frame_reg;
                offset += size;
                //g_print ("allocating local %d to %d\n", i, inst->inst_offset);
        }
 
        curinst = 0;
        if (sig->hasthis) {
-               inst = cfg->args [curinst];
-               if (inst->opcode != OP_REGVAR) {
-                       inst->opcode = OP_REGOFFSET;
-                       inst->inst_basereg = frame_reg;
+               ins = cfg->args [curinst];
+               if (ins->opcode != OP_REGVAR) {
+                       ins->opcode = OP_REGOFFSET;
+                       ins->inst_basereg = frame_reg;
                        offset += sizeof (gpointer) - 1;
                        offset &= ~(sizeof (gpointer) - 1);
-                       inst->inst_offset = offset;
+                       ins->inst_offset = offset;
                        offset += sizeof (gpointer);
                }
                curinst++;
@@ -1203,11 +1247,11 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        }                       
 
        for (i = 0; i < sig->param_count; ++i) {
-               inst = cfg->args [curinst];
+               ins = cfg->args [curinst];
 
-               if (inst->opcode != OP_REGVAR) {
-                       inst->opcode = OP_REGOFFSET;
-                       inst->inst_basereg = frame_reg;
+               if (ins->opcode != OP_REGVAR) {
+                       ins->opcode = OP_REGOFFSET;
+                       ins->inst_basereg = frame_reg;
                        size = mini_type_stack_size_full (NULL, sig->params [i], &ualign, sig->pinvoke);
                        align = ualign;
                        /* FIXME: if a structure is misaligned, our memcpy doesn't work,
@@ -1220,7 +1264,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                align = 4;
                        offset += align - 1;
                        offset &= ~(align - 1);
-                       inst->inst_offset = offset;
+                       ins->inst_offset = offset;
                        offset += size;
                }
                curinst++;
@@ -1636,6 +1680,8 @@ mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
        MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cfg->ret->dreg, val->dreg);
 }
 
+#endif /* #ifndef DISABLE_JIT */
+
 gboolean 
 mono_arch_is_inst_imm (gint64 imm)
 {
@@ -1944,6 +1990,8 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
        }
 }
 
+#ifndef DISABLE_JIT
+
 /*
  * Allow tracing to work with this interface (with an optional argument)
  */
@@ -2580,6 +2628,8 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
        return code;
 }
 
+#endif /* #ifndef DISABLE_JIT */
+
 typedef struct {
        guchar *code;
        const guchar *target;
@@ -2912,6 +2962,8 @@ mono_arm_thumb_supported (void)
        return thumb_supported;
 }
 
+#ifndef DISABLE_JIT
+
 /*
  * emit_load_volatile_arguments:
  *
@@ -3031,8 +3083,6 @@ emit_load_volatile_arguments (MonoCompile *cfg, guint8 *code)
        return code;
 }
 
-#ifndef DISABLE_JIT
-
 void
 mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 {
@@ -3767,6 +3817,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_CALL_HANDLER: 
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_target_bb);
                        ARM_BL (code, 0);
+                       mono_cfg_add_try_hole (cfg, ins->inst_eh_block, code, bb);
                        break;
                case OP_LABEL:
                        ins->inst_c0 = code - cfg->native_code;
@@ -4406,6 +4457,8 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, Mono
        }
 }
 
+#ifndef DISABLE_JIT
+
 /*
  * Stack frame layout:
  * 
@@ -4996,6 +5049,8 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 
 }
 
+#endif /* #ifndef DISABLE_JIT */
+
 static gboolean tls_offset_inited = FALSE;
 
 void
@@ -5047,6 +5102,8 @@ mono_arch_flush_register_windows (void)
 
 #ifdef MONO_ARCH_HAVE_IMT
 
+#ifndef DISABLE_JIT
+
 void
 mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg)
 {
@@ -5090,6 +5147,8 @@ mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt
        }
 }
 
+#endif /* DISABLE_JIT */
+
 MonoMethod*
 mono_arch_find_imt_method (mgreg_t *regs, guint8 *code)
 {