ImageButtonTest.cs added new tests for 2.0 and new resource NoEventValidation.aspx
[mono.git] / mono / mini / mini-codegen.c
index 6af164f43baf9585930eaad6b658146272f57005..57c1c9bbccbb78a9b05974fbc0702e141d99216d 100644 (file)
@@ -27,9 +27,12 @@ static const char*const * ins_spec = amd64_desc;
 #elif defined(__sparc__) || defined(sparc)
 const char * const sparc_desc [OP_LAST];
 static const char*const * ins_spec = sparc_desc;
+#elif defined(__mips__) || defined(mips)
+const char * const mips_desc [OP_LAST];
+static const char*const * ins_spec = mips_desc;
 #elif defined(__i386__)
-extern const char * const pentium_desc [OP_LAST];
-static const char*const * ins_spec = pentium_desc;
+extern const char * const x86_desc [OP_LAST];
+static const char*const * ins_spec = x86_desc;
 #elif defined(__ia64__)
 const char * const ia64_desc [OP_LAST];
 static const char*const * ins_spec = ia64_desc;
@@ -42,6 +45,12 @@ static const char*const * ins_spec = s390x_cpu_desc;
 #elif defined(__s390__)
 const char * const s390_cpu_desc [OP_LAST];
 static const char*const * ins_spec = s390_cpu_desc;
+#elif defined(__alpha__)
+const char * const alpha_desc [OP_LAST];
+static const char*const * ins_spec = alpha_desc;
+#elif defined(__ppc__) || defined(__powerpc__)
+extern const char * const ppcg4 [OP_LAST];
+static const char*const * ins_spec = ppcg4;
 #else
 #error "Not implemented"
 #endif
@@ -51,23 +60,22 @@ static const char*const * ins_spec = s390_cpu_desc;
 static inline GSList*
 g_slist_append_mempool (MonoMemPool *mp, GSList *list, gpointer data)
 {
-  GSList *new_list;
-  GSList *last;
-
-  new_list = mono_mempool_alloc (mp, sizeof (GSList));
-  new_list->data = data;
-  new_list->next = NULL;
-
-  if (list) {
-         last = list;
-         while (last->next)
-                 last = last->next;
-      last->next = new_list;
-
-      return list;
-    }
-  else
-      return new_list;
+       GSList *new_list;
+       GSList *last;
+       
+       new_list = mono_mempool_alloc (mp, sizeof (GSList));
+       new_list->data = data;
+       new_list->next = NULL;
+       
+       if (list) {
+               last = list;
+               while (last->next)
+                       last = last->next;
+               last->next = new_list;
+               
+               return list;
+       } else
+               return new_list;
 }
 
 /**
@@ -197,9 +205,13 @@ mono_call_inst_add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, int vreg, i
 
        regpair = (((guint32)hreg) << 24) + vreg;
        if (fp) {
+               g_assert (vreg >= MONO_MAX_FREGS);
+               g_assert (hreg < MONO_MAX_FREGS);
                call->used_fregs |= 1 << hreg;
                call->out_freg_args = g_slist_append_mempool (cfg->mempool, call->out_freg_args, (gpointer)(gssize)(regpair));
        } else {
+               g_assert (vreg >= MONO_MAX_IREGS);
+               g_assert (hreg < MONO_MAX_IREGS);
                call->used_iregs |= 1 << hreg;
                call->out_ireg_args = g_slist_append_mempool (cfg->mempool, call->out_ireg_args, (gpointer)(gssize)(regpair));
        }
@@ -238,6 +250,9 @@ mono_spillvar_offset (MonoCompile *cfg, int spillvar)
 {
        MonoSpillInfo *info;
 
+#if defined (__mips__)
+       g_assert_not_reached();
+#endif
        if (G_UNLIKELY (spillvar >= cfg->spill_info_len)) {
                resize_spill_info (cfg, FALSE);
                g_assert (spillvar < cfg->spill_info_len);
@@ -245,6 +260,9 @@ mono_spillvar_offset (MonoCompile *cfg, int spillvar)
 
        info = &cfg->spill_info [spillvar];
        if (info->offset == -1) {
+               cfg->stack_offset += sizeof (gpointer) - 1;
+               cfg->stack_offset &= ~(sizeof (gpointer) - 1);
+
                if (cfg->flags & MONO_CFG_HAS_SPILLUP) {
                        info->offset = cfg->stack_offset;
                        cfg->stack_offset += sizeof (gpointer);
@@ -269,6 +287,9 @@ mono_spillvar_offset_float (MonoCompile *cfg, int spillvar)
 {
        MonoSpillInfo *info;
 
+#if defined (__mips__)
+       g_assert_not_reached();
+#endif
        if (G_UNLIKELY (spillvar >= cfg->spill_info_float_len)) {
                resize_spill_info (cfg, TRUE);
                g_assert (spillvar < cfg->spill_info_float_len);
@@ -276,13 +297,13 @@ mono_spillvar_offset_float (MonoCompile *cfg, int spillvar)
 
        info = &cfg->spill_info_float [spillvar];
        if (info->offset == -1) {
+               cfg->stack_offset += sizeof (double) - 1;
+               cfg->stack_offset &= ~(sizeof (double) - 1);
+
                if (cfg->flags & MONO_CFG_HAS_SPILLUP) {
-                       cfg->stack_offset += 7;
-                       cfg->stack_offset &= ~7;
                        info->offset = cfg->stack_offset;
                        cfg->stack_offset += sizeof (double);
                } else {
-                       /* FIXME: align */
                        cfg->stack_offset += sizeof (double);
                        info->offset = - cfg->stack_offset;
                }
@@ -341,12 +362,13 @@ create_spilled_load_float (MonoCompile *cfg, int spill, int reg, MonoInst *ins)
 #define is_soft_reg(r,fp) (!is_hard_reg((r),(fp)))
 #define rassign(cfg,reg,fp) ((fp) ? (cfg)->rs->fassign [(reg)] : (cfg)->rs->iassign [(reg)])
 
-#define sreg1_is_fp(spec) (spec [MONO_INST_SRC1] == 'f')
-#define sreg2_is_fp(spec) (spec [MONO_INST_SRC2] == 'f')
-
 #ifdef MONO_ARCH_INST_IS_FLOAT
 #define dreg_is_fp(spec)  (MONO_ARCH_INST_IS_FLOAT (spec [MONO_INST_DEST]))
+#define sreg1_is_fp(spec) (MONO_ARCH_INST_IS_FLOAT (spec [MONO_INST_SRC1]))
+#define sreg2_is_fp(spec) (MONO_ARCH_INST_IS_FLOAT (spec [MONO_INST_SRC2]))
 #else
+#define sreg1_is_fp(spec) (spec [MONO_INST_SRC1] == 'f')
+#define sreg2_is_fp(spec) (spec [MONO_INST_SRC2] == 'f')
 #define dreg_is_fp(spec)  (spec [MONO_INST_DEST] == 'f')
 #endif
 
@@ -374,8 +396,8 @@ typedef struct {
 } RegTrack;
 
 #ifndef DISABLE_LOGGING
-static void
-print_ins (int i, MonoInst *ins)
+void
+mono_print_ins (int i, MonoInst *ins)
 {
        const char *spec = ins_spec [ins->opcode];
        printf ("\t%-2d %s", i, mono_inst_name (ins->opcode));
@@ -846,7 +868,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
        }
        reginfof = cfg->reginfof;
        if (!reginfof) {
-               cfg->reginfof_len = MAX (256, rs->next_vireg * 2);
+               cfg->reginfof_len = MAX (256, rs->next_vfreg * 2);
                reginfof = cfg->reginfof = mono_mempool_alloc (cfg->mempool, sizeof (RegTrack) * cfg->reginfof_len);
        } 
        else
@@ -875,7 +897,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
 
        i = 1;
        fpcount = 0;
-       DEBUG (printf ("LOCAL REGALLOC: BASIC BLOCK: %d\n", bb->block_num));
+       DEBUG (printf ("\nLOCAL REGALLOC: BASIC BLOCK: %d\n", bb->block_num));
        /* forward pass on the instructions to collect register liveness info */
        for (ins = bb->code; ins; ins = ins->next) {
                spec = ins_spec [ins->opcode];
@@ -884,7 +906,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_error ("Opcode '%s' missing from machine description file.", mono_inst_name (ins->opcode));
                }
                
-               DEBUG (print_ins (i, ins));
+               DEBUG (mono_print_ins (i, ins));
 
                /*
                 * TRACK FP STACK
@@ -1069,7 +1091,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                sreg2_mask = sreg2_is_fp (spec) ? MONO_ARCH_CALLEE_FREGS : MONO_ARCH_CALLEE_REGS;
 
                DEBUG (printf ("processing:"));
-               DEBUG (print_ins (i, ins));
+               DEBUG (mono_print_ins (i, ins));
 
                ip = ins->cil_code;
 
@@ -1200,6 +1222,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                        assign_ireg (cfg, rs, ins->dreg, new_dest);
                                        clob_dreg = ins->dreg;
                                        create_copy_ins (cfg, dest_sreg2, new_dest, ins, ip, FALSE);
+                                       mono_regstate_free_int (rs, dest_sreg2);
                                        need_spill = FALSE;
                                }
 
@@ -1358,7 +1381,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                        assign_reg (cfg, rs, reg2, val, fp);
 
                        dreg_high = val;
-                       ins->unused = val;
+                       ins->backend.reg3 = val;
 
                        if (reg_is_freeable (val, fp) && reg2 >= 0 && (reginfo [reg2].born_in >= i)) {
                                DEBUG (printf ("\tfreeable %s (R%d)\n", mono_arch_regname (val), reg2));
@@ -1588,7 +1611,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                                spill = -val -1;
                                        }
 
-                                       if (((ins->opcode == OP_MOVE) || (ins->opcode == OP_SETREG)) && !spill && !fp && (!is_global_ireg (ins->dreg) && (rs->ifree_mask & (regmask (ins->dreg))))) {
+                                       if (((ins->opcode == OP_MOVE) || (ins->opcode == OP_SETREG)) && !spill && !fp && (is_local_ireg (ins->dreg) && (rs->ifree_mask & (regmask (ins->dreg))))) {
                                                /* 
                                                 * Allocate the same hreg to sreg1 as well so the 
                                                 * peephole can get rid of the move.
@@ -1737,8 +1760,14 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                val = alloc_reg (cfg, tmp, ins, sreg2_mask, ins->sreg2, &reginfo [ins->sreg2], fp);
                                assign_reg (cfg, rs, ins->sreg2, val, fp);
                                DEBUG (printf ("\tassigned sreg2 %s to R%d\n", mono_regname_full (val, fp), ins->sreg2));
-                               if (spill)
-                                       create_spilled_store (cfg, spill, val, prev_sreg2, ins, fp);
+                               if (spill) {
+                                       MonoInst *store = create_spilled_store (cfg, spill, val, prev_sreg2, NULL, fp);
+                                       /*
+                                        * Need to insert before the instruction since it can
+                                        * overwrite sreg2.
+                                        */
+                                       insert_before_ins (ins, tmp, store);
+                               }
                        }
                        ins->sreg2 = val;
                }
@@ -1755,7 +1784,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                        mono_regstate2_free_int (rs, ins->sreg2);
                }*/
        
-               DEBUG (print_ins (i, ins));
+               DEBUG (mono_print_ins (i, ins));
                /* this may result from a insert_before call */
                if (!tmp->next)
                        bb->code = tmp->data;