Don't assert on broken DM names.
[mono.git] / mono / mini / mini-alpha.c
index e7d5ebb7b73141a7a093ae307a30ede2f5ded886..404227abb5c60ba28ecb5a93dc23fe4e39493e84 100644 (file)
 
 #define ALPHA_PRINT if (mini_alpha_verbose_level)
 
-#define NEW_INS(cfg,ins,dest,op) do {                                  \
+#define NEW_INS(cfg,dest,op) do {       \
    (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));       \
    (dest)->opcode = (op);  \
-   MONO_INST_LIST_ADD_TAIL (&(dest)->node, &(ins)->node);
+   insert_after_ins (bb, last_ins, (dest)); \
 } while (0)
 
-#define NEW_ICONST(cfg,dest,val) do {                                  \
-    (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));  \
-    (dest)->opcode = OP_ICONST;                                                \
-    (dest)->inst_c0 = (val);                                           \
-    (dest)->type = STACK_I4;                                           \
-  } while (0)
-
-
 #undef DEBUG
 #define DEBUG(a) if (cfg->verbose_level > 1) a
 
@@ -67,7 +59,6 @@
 
 #include "trace.h"
 #include "mini-alpha.h"
-#include "inssel.h"
 #include "cpu-alpha.h"
 #include "jit-icalls.h"
 
@@ -91,6 +82,9 @@ pthread_key_t lmf_addr_key;
 
 gboolean lmf_addr_key_inited = FALSE;
 
+MonoBreakpointInfo
+mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 /*====================== End of Global Variables ===================*/
 
 gpointer mono_arch_get_lmf_addr (void);
@@ -191,7 +185,7 @@ add_float (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo,
 }
 
 static void
-add_valuetype (MonoGenericSharingContext *ctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
                gboolean is_return,
                guint32 *gr, guint32 *fr, guint32 *stack_size)
 {
@@ -291,6 +285,22 @@ add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg,
     }
 }
 
+static void
+insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert)
+{
+   if (ins == NULL)
+     {
+       ins = bb->code;
+       bb->code = to_insert;
+       to_insert->next = ins;
+     }
+   else
+     {
+       to_insert->next = ins->next;
+       ins->next = to_insert;
+     }
+}
+
 static void add_got_entry(MonoCompile *cfg, AlphaGotType ge_type,
                          AlphaGotData ge_data,
                          int ip, MonoJumpInfoType type, gconstpointer target)
@@ -419,20 +429,28 @@ mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
 
 /*========================= End of Function ========================*/
 
-static void
-  peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
+// This peephole function is called before "local_regalloc" method
+// TSV_TODO - Check what we need to move here
+void
+mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb)
 {
-  MonoInst *ins, *n;
+  CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE_1 pass\n");
+}
+
+// This peephole function is called after "local_regalloc" method
+void
+mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
+{
+  MonoInst *ins, *n, *last_ins = NULL;
+  ins = bb->code;
    
-  CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE pass\n");
+  CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE_2 pass\n");
 
-  MONO_INST_LIST_FOR_EACH_ENTRY_SAFE (ins, n, &bb->ins_list, node) {
-      MonoInst *last_ins = mono_inst_list_prev (&ins->node, &bb->ins_list);
+  MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
       switch (ins->opcode) 
        {        
        case OP_MOVE:
        case OP_FMOVE:
-       case OP_SETREG:
          /*
           * Removes:
           *
@@ -441,7 +459,7 @@ static void
          if (ins->dreg == ins->sreg1 &&
              ins->dreg != alpha_at) 
            {
-             MONO_DEL_INS (ins);
+             MONO_DELETE_INS (bb, ins);
              continue;
            }
          
@@ -456,7 +474,7 @@ static void
              last_ins->dreg != alpha_at &&
              ins->dreg == last_ins->sreg1) 
            {
-             MONO_DEL_INS (ins);
+             MONO_DELETE_INS (bb, ins);
              continue;
            }
          
@@ -472,7 +490,7 @@ static void
                }
              else 
                {
-                 MONO_DEL_INS (ins);
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
            }
@@ -498,7 +516,7 @@ static void
             {
               if (ins->dreg == last_ins->sreg1)
                 {
-                 MONO_DEL_INS (ins);
+                 MONO_DELETE_INS (bb, ins);
                   continue;
                 }
               else
@@ -529,7 +547,7 @@ static void
            {
              if (ins->dreg == last_ins->sreg1)
                {
-                 MONO_DEL_INS (ins);
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
              else
@@ -558,7 +576,7 @@ static void
            {
              if (ins->dreg == last_ins->dreg)
                {
-                 MONO_DEL_INS (ins);
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
              else
@@ -572,11 +590,14 @@ static void
          break;      
 #endif
        }
+      
+      last_ins = ins;
+      ins = ins->next;
     }
+   
+  bb->last_ins = last_ins;
 }
 
-
-
 // Convert to opposite branch opcode
 static guint16 cvt_branch_opcode(guint16 opcode)
 {
@@ -908,13 +929,13 @@ static void cvt_cmp_branch(MonoInst *curr, MonoInst *next)
  * Converts complex opcodes into simpler ones so that each IR instruction
  * corresponds to one machine instruction.
  */
-static void
-  mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
+void
+mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
 {   
-   MonoInst *ins, *n, *next, *temp;
+   MonoInst *ins, *n, *temp, *last_ins = NULL;
+   MonoInst *next;
    
-   if (bb->max_vreg > cfg->rs->next_vreg)
-        cfg->rs->next_vreg = bb->max_vreg;
+   ins = bb->code;
    
    /*
     * FIXME: Need to add more instructions, but the current machine
@@ -922,7 +943,7 @@ static void
     * cdq.
     */
    
-   MONO_INST_LIST_FOR_EACH_ENTRY_SAFE (ins, n, &bb->ins_list, node) {
+   MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
        switch (ins->opcode) 
         {       
         case OP_DIV_IMM:
@@ -930,9 +951,9 @@ static void
         case OP_IDIV_IMM:
         case OP_IREM_IMM:
         case OP_MUL_IMM:
-          NEW_INS (cfg, ins, temp, OP_I8CONST);
+          NEW_INS (cfg, temp, OP_I8CONST);
           temp->inst_c0 = ins->inst_imm;
-          temp->dreg = mono_regstate_next_int (cfg->rs);
+          temp->dreg = mono_alloc_ireg (cfg);
           
           switch (ins->opcode) 
             {
@@ -964,8 +985,7 @@ static void
             // Instead of compare+b<cond>/fcompare+b<cond>,
             // Alpha has compare<cond>+br<cond>/fcompare<cond>+br<cond>
             // we need to convert
-            next = mono_inst_list_next (&ins->node, &bb->ins_list);
-            g_assert(next);
+            next = ins->next;
 
             cvt_cmp_branch(ins, next);
           }
@@ -974,18 +994,17 @@ static void
         case OP_COMPARE_IMM:
           if (!alpha_is_imm (ins->inst_imm)) 
             {    
-              NEW_INS (cfg, ins, temp, OP_I8CONST);
+              NEW_INS (cfg, temp, OP_I8CONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int (cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
               ins->opcode = OP_COMPARE;
               ins->sreg2 = temp->dreg;
                                  
               // We should try to reevaluate new IR opcode
-              continue;
+              //continue;
             }
           
-          next = mono_inst_list_next (&ins->node, &bb->ins_list);
-          g_assert(next);
+          next = ins->next;
           
           cvt_cmp_branch(ins, next);
                         
@@ -994,18 +1013,17 @@ static void
         case OP_ICOMPARE_IMM:
            if (!alpha_is_imm (ins->inst_imm))
              {
-              NEW_INS (cfg, ins, temp, OP_ICONST);
+               NEW_INS (cfg, temp, OP_ICONST);
                temp->inst_c0 = ins->inst_imm;
-               temp->dreg = mono_regstate_next_int (cfg->rs);
+               temp->dreg = mono_alloc_ireg (cfg);
                ins->opcode = OP_ICOMPARE;
                ins->sreg2 = temp->dreg;
 
                // We should try to reevaluate new IR opcode
-               continue;
+               //continue;
              }
 
-          next = mono_inst_list_next (&ins->node, &bb->ins_list);
-          g_assert(next);
+           next = ins->next;
 
            cvt_cmp_branch(ins, next);
 
@@ -1015,9 +1033,9 @@ static void
         case OP_STOREI8_MEMBASE_IMM:
           if (ins->inst_imm != 0) 
             {    
-              NEW_INS (cfg, ins, temp, OP_I8CONST);
+              NEW_INS (cfg, temp, OP_I8CONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int (cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
               ins->opcode = OP_STOREI8_MEMBASE_REG;
               ins->sreg1 = temp->dreg;
             }
@@ -1027,9 +1045,9 @@ static void
           if (ins->inst_imm != 0)
             {
               MonoInst *temp;
-              NEW_INS (cfg, ins, temp, OP_ICONST);
+              NEW_INS (cfg, temp, OP_ICONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int (cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
               ins->opcode = OP_STOREI4_MEMBASE_REG;
               ins->sreg1 = temp->dreg;
             }
@@ -1039,9 +1057,9 @@ static void
           if (ins->inst_imm != 0 || !bwx_supported)
              {
                MonoInst *temp;
-               NEW_INS (cfg, ins, temp, OP_ICONST);
+               NEW_INS (cfg, temp, OP_ICONST);
                temp->inst_c0 = ins->inst_imm;
-               temp->dreg = mono_regstate_next_int (cfg->rs);
+               temp->dreg = mono_alloc_ireg (cfg);
                ins->opcode = OP_STOREI1_MEMBASE_REG;
                ins->sreg1 = temp->dreg;
              }
@@ -1051,9 +1069,9 @@ static void
            if (ins->inst_imm != 0 || !bwx_supported)
           {
             MonoInst *temp;
-            NEW_INS (cfg, ins, temp, OP_ICONST);
+            NEW_INS (cfg, temp, OP_ICONST);
             temp->inst_c0 = ins->inst_imm;
-            temp->dreg = mono_regstate_next_int (cfg->rs);
+            temp->dreg = mono_alloc_ireg (cfg);
             ins->opcode = OP_STOREI2_MEMBASE_REG;
             ins->sreg1 = temp->dreg;
           }
@@ -1070,9 +1088,9 @@ static void
           if (!alpha_is_imm(ins->inst_imm))
             {
               MonoInst *temp;
-              NEW_INS (cfg, ins, temp, OP_ICONST);
+              NEW_INS (cfg, temp, OP_ICONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int (cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
                                  
               switch(ins->opcode)
                 {
@@ -1113,9 +1131,9 @@ static void
           if (!alpha_is_imm(ins->inst_imm))
             {
               MonoInst *temp;
-              NEW_INS (cfg, ins, temp, OP_ICONST);
+              NEW_INS (cfg, temp, OP_ICONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int (cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
               
               switch(ins->opcode)
                 {
@@ -1142,9 +1160,9 @@ static void
           if (!alpha_is_imm(ins->inst_imm))
             {
               MonoInst *temp;
-              NEW_INS(cfg, ins, temp, OP_ICONST);
+              NEW_INS(cfg, temp, OP_ICONST);
               temp->inst_c0 = ins->inst_imm;
-              temp->dreg = mono_regstate_next_int(cfg->rs);
+              temp->dreg = mono_alloc_ireg (cfg);
               ins->sreg2 = temp->dreg;
               ins->opcode = OP_LSHR;
             }
@@ -1153,9 +1171,9 @@ static void
            if (!alpha_is_imm(ins->inst_imm))
              {
                MonoInst *temp;
-               NEW_INS(cfg, ins, temp, OP_ICONST);
+               NEW_INS(cfg, temp, OP_ICONST);
                temp->inst_c0 = ins->inst_imm;
-               temp->dreg = mono_regstate_next_int(cfg->rs);
+               temp->dreg = mono_alloc_ireg (cfg);
                ins->sreg2 = temp->dreg;
                ins->opcode = OP_LSHL;
              }
@@ -1164,36 +1182,14 @@ static void
         default:
           break;
         }
+               
+       last_ins = ins;
+       ins = ins->next;
      }
    
-   bb->max_vreg = cfg->rs->next_vreg;
-}
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name         - mono_arch_local_regalloc.                         */
-/*                                                                  */
-/* Function     - We first scan the list of instructions and we     */
-/*                save the liveness information of each register    */
-/*                (when the register is first used, when its value  */
-/*                is set etc.). We also reverse the list of instr-  */
-/*                uctions (in the InstList list) because assigning  */
-/*                registers backwards allows for more tricks to be  */
-/*                used.                                             */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
-{
-  CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_local_regalloc");
-   
-  if (MONO_INST_LIST_EMPTY (&bb->ins_list))
-    return;
-   
-  mono_arch_lowering_pass (cfg, bb);
+   bb->last_ins = last_ins;
    
-  mono_local_regalloc(cfg, bb);
+   bb->max_vreg = cfg->next_vreg;
 }
 
 /*========================= End of Function ========================*/
@@ -2110,26 +2106,6 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 #define EMIT_ALPHA_BRANCH(Tins, PRED_REG, ALPHA_BR)    \
   offset = ((char *)code -                      \
            (char *)cfg->native_code);          \
-  if (Tins->flags & MONO_INST_BRLABEL)         \
-    {                                          \
-      if (Tins->inst_i0->inst_c0)              \
-       {                                                               \
-         CFG_DEBUG(3) g_print("inst_c0: %0lX, data: %p]\n",            \
-                Tins->inst_i0->inst_c0,                                \
-                cfg->native_code + Tins->inst_i0->inst_c0);            \
-         alpha_##ALPHA_BR (code, PRED_REG, 0);                         \
-       }                                                               \
-      else                                                             \
-       {                                                               \
-         CFG_DEBUG(3) g_print("add patch info: MONO_PATCH_INFO_LABEL offset: %0X, inst_i0: %p]\n", \
-                offset, Tins->inst_i0);                                \
-         mono_add_patch_info (cfg, offset,                             \
-                              MONO_PATCH_INFO_LABEL, Tins->inst_i0);   \
-         alpha_##ALPHA_BR (code, PRED_REG, 0);                         \
-       }                                                               \
-    }                                                                  \
-  else                                                                 \
-    {                                                                  \
       if (Tins->inst_true_bb->native_offset)                           \
        {                                                               \
          long br_offset = (char *)cfg->native_code +                   \
@@ -2148,8 +2124,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                               MONO_PATCH_INFO_BB,                      \
                               Tins->inst_true_bb);                     \
          alpha_##ALPHA_BR (code, PRED_REG, 0);                         \
-       }                                                               \
-    }
+       }
 
 
 #define EMIT_COND_EXC_BRANCH(ALPHA_BR, PRED_REG, EXC_NAME)             \
@@ -2189,14 +2164,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
    MonoCallInst *call;
    guint offset;
    unsigned int *code = (unsigned int *)(cfg->native_code + cfg->code_len);
+   MonoInst *last_ins = NULL;
    guint last_offset = 0;
    int max_len, cpos;
    
    CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_output_basic_block");
    
-   if (cfg->opt & MONO_OPT_PEEPHOLE)
-     peephole_pass (cfg, bb);
-    
    CFG_DEBUG(2) g_print ("Basic block %d(%p) starting at offset 0x%x\n",
                         bb->block_num, bb, bb->native_offset);
    
@@ -2226,6 +2199,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
          
        switch (ins->opcode)
         {
+        case OP_RELAXED_NOP:
+               break;
         case OP_LSHR:
           // Shift 64 bit value right
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr] dreg=%d, sreg1=%d, sreg2=%d\n",
@@ -3617,51 +3592,32 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           break;
           
         case OP_BR:
-          if (ins->flags & MONO_INST_BRLABEL)
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [br] target: %p, next: %p, curr: %p, last: %p [",
+                 ins->inst_target_bb, bb->next_bb, ins, bb->last_ins);
+          
+          if (ins->inst_target_bb->native_offset)
             {
-              if (ins->inst_i0->inst_c0)
-                {
-                  CFG_DEBUG(4) g_print("inst_c0: %0lX, data: %p]\n",
-                         ins->inst_i0->inst_c0,
-                         cfg->native_code + ins->inst_i0->inst_c0);
-                  alpha_br(code, alpha_zero, 0);
-                }
-              else
-                {
-                  CFG_DEBUG(4) g_print("add patch info: MONO_PATCH_INFO_LABEL offset: %0X, inst_i0: %p]\n",
-                         offset, ins->inst_i0);
-                  mono_add_patch_info (cfg, offset,
-                                       MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                  
-                  alpha_br(code, alpha_zero, 0);
-                }
+              // Somehow native offset is offset from
+              // start of the code. So convert it to
+              // offset branch
+              long br_offset = (char *)cfg->native_code +
+                ins->inst_target_bb->native_offset - 4 - (char *)code;
+
+              CFG_DEBUG(4) g_print("jump to: native_offset: %0X, address %p]\n",
+                     ins->inst_target_bb->native_offset,
+                     cfg->native_code +
+                     ins->inst_target_bb->native_offset);
+              alpha_br(code, alpha_zero, br_offset/4);
             }
           else
             {
-              if (ins->inst_target_bb->native_offset)
-                {
-                  // Somehow native offset is offset from
-                  // start of the code. So convert it to
-                  // offset branch
-                  long br_offset = (char *)cfg->native_code +
-                    ins->inst_target_bb->native_offset - 4 - (char *)code;
-                  
-                  CFG_DEBUG(4) g_print("jump to: native_offset: %0X, address %p]\n",
-                         ins->inst_target_bb->native_offset,
-                         cfg->native_code +
-                         ins->inst_target_bb->native_offset);
-                  alpha_br(code, alpha_zero, br_offset/4);
-                }
-              else
-                {
-                  CFG_DEBUG(4) g_print("add patch info: MONO_PATCH_INFO_BB offset: %0X, target_bb: %p]\n",
-                         offset, ins->inst_target_bb);
-                  
-                  mono_add_patch_info (cfg, offset,
-                                       MONO_PATCH_INFO_BB,
-                                       ins->inst_target_bb);
-                  alpha_br(code, alpha_zero, 0);
-                }
+              CFG_DEBUG(4) g_print("add patch info: MONO_PATCH_INFO_BB offset: %0X, target_bb: %p]\n",
+                     offset, ins->inst_target_bb);
+
+              mono_add_patch_info (cfg, offset,
+                                   MONO_PATCH_INFO_BB,
+                                   ins->inst_target_bb);
+              alpha_br(code, alpha_zero, 0);
             }
           
           break;
@@ -3677,7 +3633,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
         case OP_LCALL:
         case OP_VCALL:
         case OP_VOIDCALL:
-        case CEE_CALL:
+        case OP_CALL:
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [fcall/lcall/vcall/voidcall/call] Target: [");
           call = (MonoCallInst*)ins;
           
@@ -3823,12 +3779,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
             alpha_bsr(code, alpha_ra, 0);
           }
           break;
-          
-        case CEE_RET:
-          CFG_DEBUG(4) g_print("ALPHA_CHECK: [ret]\n");
-          
-          alpha_ret(code, alpha_ra, 1);
-          break;
 
         case OP_THROW:
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [throw] sreg1=%0x\n",
@@ -3957,8 +3907,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        
        cpos += max_len;
        
+       last_ins = ins;
        last_offset = offset;
-     }
+   }
    
    cfg->code_len = ((char *)code) - ((char *)cfg->native_code);
 }
@@ -4286,7 +4237,7 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst,
        {
          MONO_INST_NEW (cfg, vtarg, OP_MOVE);
          vtarg->sreg1 = vt_reg;
-         vtarg->dreg = mono_regstate_next_int (cfg->rs);
+         vtarg->dreg = mono_alloc_ireg (cfg);
          mono_bblock_add_inst (cfg->cbb, vtarg);
 
          mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg,
@@ -4301,7 +4252,7 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst,
       MONO_INST_NEW (cfg, this, OP_MOVE);
       this->type = this_type;
       this->sreg1 = this_reg;
-      this->dreg = mono_regstate_next_int (cfg->rs);
+      this->dreg = mono_alloc_ireg (cfg);
       mono_bblock_add_inst (cfg->cbb, this);
 
       mono_call_inst_add_outarg_reg (cfg, call, this->dreg,
@@ -4471,7 +4422,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gbool
        cinfo->ret.reg = alpha_f0;
        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 = alpha_r0;
@@ -4574,7 +4525,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gbool
         add_general (pgr, &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 (pgr, &stack_size, ainfo);
             break;
@@ -4790,7 +4741,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
           MONO_INST_NEW (cfg, arg, OP_OUTARG);
           arg->inst_left = sig_arg;
           arg->type = STACK_PTR;
-          MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+          
+          /* prepend, so they get reversed */
+          arg->next = call->out_args;
+          call->out_args = arg;
         }
                
        if (is_virtual && i == 0) {
@@ -4805,7 +4759,9 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
         arg->cil_code = in->cil_code;
         arg->inst_left = in;
         arg->type = in->type;
-        MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+        /* prepend, so they get reversed */
+        arg->next = call->out_args;
+        call->out_args = arg;
 
         CFG_DEBUG(3) g_print("ALPHA: Param[%d] - ", i);
 
@@ -4873,9 +4829,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
 
                     add_outarg_reg (cfg, call, set_reg, arg_storage,
                                     dest_reg, load);
-                    if (&set_reg->node != call->out_args.next)
+                    if (set_reg != call->out_args)
                       {
-                        MONO_INST_LIST_ADD (&set_reg->node, &call->out_args);
+                        set_reg->next = call->out_args;
+                        call->out_args = set_reg;
                     }
                   }
 
@@ -4909,9 +4866,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                     //outarg->inst_imm = 16 + ainfo->offset + (slot - 8) * 8;
                     outarg->dreg = ainfo->offset + (slot - 22) * 8;
 
-                    if (&outarg->node != call->out_args.next)
+                    if (outarg != call->out_args)
                       {
-                        MONO_INST_LIST_ADD (&outarg->node, &call->out_args);
+                        outarg->next = call->out_args;
+                        call->out_args = outarg;
                       }
                   }
                
@@ -4922,7 +4880,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                 arg->inst_left = vtaddr;
                 arg->inst_right = in;
                 arg->type = in->type;
-                MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+
+                /* prepend, so they get reversed */
+                arg->next = call->out_args;
+                call->out_args = arg;
               }
             else
               {
@@ -5002,7 +4963,9 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
         zero_inst->inst_p0 = 0;
         arg->inst_left = zero_inst;
         arg->type = STACK_PTR;
-        MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+        /* prepend, so they get reversed */
+        arg->next = call->out_args;
+        call->out_args = arg;
        }
        else
         /* if the function returns a struct, the called method a
@@ -5090,7 +5053,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
 
    CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_get_allocatable_int_vars");
 
-   header = mono_method_get_header (cfg->method);
+   header = cfg->header;
 
    sig = mono_method_signature (cfg->method);
 
@@ -5167,31 +5130,6 @@ mono_arch_get_domain_intrinsic (MonoCompile* cfg)
 
 /*========================= End of Function ========================*/
 
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name         - mono_arch_get_thread_intrinsic                    */
-/*                                                                  */
-/* Function     -                                                   */
-/*                                                                  */
-/* Returns      -                                                   */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-MonoInst *
-mono_arch_get_thread_intrinsic (MonoCompile* cfg)
-{
-   MonoInst *ins;
-   
-   if (thread_tls_offset == -1)
-        return NULL;
-   
-   MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-   ins->inst_offset = thread_tls_offset;
-   return (ins);
-}
-
-/*========================= End of Function ========================*/
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name         - mono_arch_get_inst_for_method                   */
@@ -5211,11 +5149,6 @@ mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod,
    
    CFG_DEBUG(3) g_print("mono_arch_get_inst_for_method: %s\n", cmethod->name);
    
-   if (cmethod->klass == mono_defaults.thread_class &&
-       strcmp (cmethod->name, "MemoryBarrier") == 0) {
-     MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER);
-   }
-   
    return ins;
 }
 
@@ -5357,8 +5290,7 @@ enum {
 /*------------------------------------------------------------------*/
 
 void*
-mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p,
-       gboolean enable_arguments)
+mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers)
 {
   unsigned int *code = p;
   int save_mode = SAVE_NONE;
@@ -5521,7 +5453,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
    
    CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_allocate_vars");
    
-   header = mono_method_get_header (cfg->method);
+   header = cfg->header;
    
    sig = mono_method_signature (cfg->method);
    
@@ -5849,7 +5781,7 @@ mono_arch_print_tree (MonoInst *tree, int arity)
 */
 
 gpointer*
-mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
+mono_arch_get_vcall_slot_addr (guint8* code, mgreg_t *regs)
 {
   unsigned int *pc = (unsigned int *)code;
   guint32 reg, disp;
@@ -5900,9 +5832,45 @@ mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
   return 0;
 }
 
+gpointer
+mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, mgreg_t *regs, guint8 *code)
+{
+  unsigned int *pc = (unsigned int *)code;
+
+  ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_this_arg_from_call] code: %p regs: %p",
+          pc, regs);
+
+        if (MONO_TYPE_ISSTRUCT (sig->ret))
+                return (gpointer)regs [alpha_a1];
+        else
+                return (gpointer)regs [alpha_a0];
+}
+
+gpointer
+mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
+{
+       unsigned int *code, *start;
+        MonoDomain *domain = mono_domain_get ();
+        int i;
+
+       ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_delegate_invoke_impl]");
+
+        /* FIXME: Support more cases */
+        if (MONO_TYPE_ISSTRUCT (sig->ret))
+                return NULL;
+
+       return NULL;
+}
 
 guint32
 mono_arch_get_patch_offset (guint8 *code)
 {
   return 3;
 }
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}