2007-10-19 Marek Habersack <mhabersack@novell.com>
[mono.git] / mono / mini / mini-codegen.c
index 7ad6e29adfe2ad5ae5f37b3682e0a200b3be3ed0..d4b1acb282129d0a6736c2cf160d801cb555cab7 100644 (file)
@@ -6,7 +6,9 @@
 
 #include <string.h>
 #include <math.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
@@ -452,7 +454,7 @@ struct InstList {
 static inline InstList*
 inst_list_prepend (guint8 *mem, InstList *list, MonoInst *data)
 {
-       InstList *item = (InstList*)mem;
+       InstList *item = (InstList*)(gpointer)mem;
        item->data = data;
        item->prev = NULL;
        item->next = list;
@@ -766,7 +768,10 @@ assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, gboolean fp)
        else {
                g_assert (reg >= MONO_MAX_IREGS);
                g_assert (hreg < MONO_MAX_IREGS);
+#ifndef __arm__
+               /* this seems to trigger a gcc compilation bug sometime (hreg is 0) */
                g_assert (! is_global_ireg (hreg));
+#endif
 
                rs->vassign [reg] = hreg;
                rs->isymbolic [hreg] = reg;
@@ -1138,8 +1143,18 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                        insert_before_ins (ins, tmp, copy);
                                }
                                else {
-                                       DEBUG (printf ("\tshortcut assignment of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
-                                       assign_ireg (cfg, rs, ins->sreg2, dest_sreg2);
+                                       val = rs->vassign [ins->sreg2];
+                                       if (val == -1) {
+                                               DEBUG (printf ("\tshortcut assignment of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
+                                               assign_reg (cfg, rs, ins->sreg2, dest_sreg2, FALSE);
+                                       } else if (val < -1) {
+                                               /* FIXME: */
+                                               g_assert_not_reached ();
+                                       } else {
+                                               /* Argument already in hard reg, need to copy */
+                                               MonoInst *copy = create_copy_ins (cfg, dest_sreg2, val, NULL, ip, FALSE);
+                                               insert_before_ins (ins, tmp, copy);
+                                       }
                                }
                        } else {
                                int need_spill = TRUE;