[xbuild] Vbc task - make error column check a little non-specific.
[mono.git] / mono / mini / mini-alpha.c
index 87ea4da1114acb01005dd5a77a73ecb9d4f8e696..f7f8a36aac231666c7c1d79d9bed8f848f94eb9c 100644 (file)
 /*------------------------------------------------------------------*/
 /*                 D e f i n e s                                    */
 /*------------------------------------------------------------------*/
-
-#define NOT_IMPLEMENTED(x) \
-   g_error ("FIXME: %s is not yet implemented.", x);
-
 #define ALPHA_DEBUG(x) \
    if (mini_alpha_verbose_level) \
        g_debug ("ALPHA_DEBUG: %s is called.", x);
    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
 
@@ -71,8 +59,8 @@
 
 #include "trace.h"
 #include "mini-alpha.h"
-#include "inssel.h"
 #include "cpu-alpha.h"
+#include "jit-icalls.h"
 
 /*========================= End of Includes ========================*/
 
@@ -84,8 +72,6 @@ static int indent_level = 0;
 int mini_alpha_verbose_level = 0;
 static int bwx_supported = 0;
 
-static const char*const * ins_spec = alpha_desc;
-
 static gboolean tls_offset_inited = FALSE;
 
 static int appdomain_tls_offset = -1,
@@ -96,9 +82,11 @@ pthread_key_t lmf_addr_key;
 
 gboolean lmf_addr_key_inited = FALSE;
 
+MonoBreakpointInfo
+mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 /*====================== End of Global Variables ===================*/
 
-static void mono_arch_break(void);
 gpointer mono_arch_get_lmf_addr (void);
 
 typedef enum {
@@ -136,7 +124,7 @@ typedef struct {
    ArgInfo args [1];
 } CallInfo;
 
-static CallInfo* get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke);
+static CallInfo* get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke);
 static unsigned int *emit_call(MonoCompile *cfg, unsigned int *code,
                               guint32 patch_type, gconstpointer data);
 
@@ -197,15 +185,15 @@ add_float (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo,
 }
 
 static void
-add_valuetype (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)
 {
-  guint32 size, i;
+  guint32 size;
   MonoClass *klass;
   MonoMarshalType *info;
-  gboolean is_hfa = TRUE;
-  guint32 hfa_type = 0;
+  //gboolean is_hfa = TRUE;
+  //guint32 hfa_type = 0;
 
   klass = mono_class_from_mono_type (type);
   if (type->type == MONO_TYPE_TYPEDBYREF)
@@ -213,7 +201,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
   else if (sig->pinvoke)
     size = mono_type_native_stack_size (&klass->byval_arg, NULL);
   else
-    size = mono_type_stack_size (&klass->byval_arg, NULL);
+    size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
 
   if (!sig->pinvoke || (size == 0) || is_return) {
     /* Allways pass in memory */
@@ -396,7 +384,7 @@ mono_arch_create_vars (MonoCompile *cfg)
    
   sig = mono_method_signature (cfg->method);
    
-  cinfo = get_call_info (sig, FALSE);
+  cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
    
   if (cinfo->ret.storage == ArgValuetypeInReg)
     cfg->ret_var_is_local = TRUE;
@@ -441,21 +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)
+{
+  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, *last_ins = NULL;
+  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");
 
-  while (ins) 
-    {  
+  MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
       switch (ins->opcode) 
        {        
        case OP_MOVE:
        case OP_FMOVE:
-       case OP_SETREG:
          /*
           * Removes:
           *
@@ -464,10 +459,7 @@ static void
          if (ins->dreg == ins->sreg1 &&
              ins->dreg != alpha_at) 
            {
-             if (last_ins)
-               last_ins->next = ins->next;
-             
-             ins = ins->next;
+             MONO_DELETE_INS (bb, ins);
              continue;
            }
          
@@ -482,9 +474,7 @@ static void
              last_ins->dreg != alpha_at &&
              ins->dreg == last_ins->sreg1) 
            {
-             last_ins->next = ins->next;
-             
-             ins = ins->next;
+             MONO_DELETE_INS (bb, ins);
              continue;
            }
          
@@ -500,8 +490,7 @@ static void
                }
              else 
                {
-                 last_ins->next = ins->next;
-                 ins = ins->next;
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
            }
@@ -527,9 +516,7 @@ static void
             {
               if (ins->dreg == last_ins->sreg1)
                 {
-                  last_ins->next = ins->next;
-
-                  ins = ins->next;
+                 MONO_DELETE_INS (bb, ins);
                   continue;
                 }
               else
@@ -560,9 +547,7 @@ static void
            {
              if (ins->dreg == last_ins->sreg1)
                {
-                 last_ins->next = ins->next;
-
-                 ins = ins->next;
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
              else
@@ -591,9 +576,7 @@ static void
            {
              if (ins->dreg == last_ins->dreg)
                {
-                 last_ins->next = ins->next;
-                 
-                 ins = ins->next;
+                 MONO_DELETE_INS (bb, ins);
                  continue;
                }
              else
@@ -615,8 +598,6 @@ static void
   bb->last_ins = last_ins;
 }
 
-
-
 // Convert to opposite branch opcode
 static guint16 cvt_branch_opcode(guint16 opcode)
 {
@@ -948,27 +929,21 @@ 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, *temp, *last_ins = NULL;
+   MonoInst *ins, *n, *temp, *last_ins = NULL;
    MonoInst *next;
    
    ins = bb->code;
    
-   if (bb->max_ireg > cfg->rs->next_vireg)
-        cfg->rs->next_vireg = bb->max_ireg;
-   if (bb->max_freg > cfg->rs->next_vfreg)
-        cfg->rs->next_vfreg = bb->max_freg;
-   
    /*
     * FIXME: Need to add more instructions, but the current machine
     * description can't model some parts of the composite instructions like
     * cdq.
     */
    
-   while (ins) 
-     {
+   MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
        switch (ins->opcode) 
         {       
         case OP_DIV_IMM:
@@ -978,7 +953,7 @@ static void
         case OP_MUL_IMM:
           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) 
             {
@@ -1021,12 +996,12 @@ static void
             {    
               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 = ins->next;
@@ -1040,12 +1015,12 @@ static void
              {
                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 = ins->next;
@@ -1060,7 +1035,7 @@ static void
             {    
               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;
             }
@@ -1072,7 +1047,7 @@ static void
               MonoInst *temp;
               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;
             }
@@ -1084,7 +1059,7 @@ static void
                MonoInst *temp;
                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;
              }
@@ -1096,7 +1071,7 @@ static void
             MonoInst *temp;
             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;
           }
@@ -1115,7 +1090,7 @@ static void
               MonoInst *temp;
               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)
                 {
@@ -1158,7 +1133,7 @@ static void
               MonoInst *temp;
               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)
                 {
@@ -1187,7 +1162,7 @@ static void
               MonoInst *temp;
               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;
             }
@@ -1198,7 +1173,7 @@ static void
                MonoInst *temp;
                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;
              }
@@ -1214,35 +1189,7 @@ static void
    
    bb->last_ins = last_ins;
    
-   bb->max_ireg = cfg->rs->next_vireg;
-   bb->max_freg = cfg->rs->next_vfreg;
-}
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* 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 (!bb->code)
-    return;
-   
-  mono_arch_lowering_pass (cfg, bb);
-   
-  mono_local_regalloc(cfg, bb);
+   bb->max_vreg = cfg->next_vreg;
 }
 
 /*========================= End of Function ========================*/
@@ -1346,7 +1293,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, unsigned int *code)
 
   sig = mono_method_signature (method);
 
-  cinfo = get_call_info (sig, FALSE);
+  cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
 
   if (sig->ret->type != MONO_TYPE_VOID) {
     if ((cinfo->ret.storage == ArgInIReg) &&
@@ -1360,7 +1307,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, unsigned int *code)
   for (i = 0; i < sig->param_count + sig->hasthis; ++i)
     {
       ArgInfo *ainfo = &cinfo->args [i];
-      MonoInst *inst = cfg->varinfo [i];
+      MonoInst *inst = cfg->args [i];
 
       switch(ainfo->storage)
        {
@@ -1505,7 +1452,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
    
    offset = cfg->arch.args_save_area_offset;
 
-   cinfo = get_call_info (sig, FALSE);
+   cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
 
    if (sig->ret->type != MONO_TYPE_VOID)
      {
@@ -1522,7 +1469,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
    for (i = 0; i < sig->param_count + sig->hasthis; ++i)
      {
        ArgInfo *ainfo = &cinfo->args [i];
-       MonoInst *inst = cfg->varinfo [i];
+       MonoInst *inst = cfg->args [i];
        int j;
 
        switch(ainfo->storage)
@@ -1554,7 +1501,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
               {
                 CFG_DEBUG(3) g_print("ALPHA: Saved aggregate arg reg %d at offset: %0lx\n",
                                      ainfo->reg + j, inst->inst_offset + (8*j));
-                alpha_stq(code, ainfo->reg+j, inst->inst_basereg,
+                alpha_stq(code, (ainfo->reg+j), inst->inst_basereg,
                           (inst->inst_offset + (8*j)));
                 offset += 8;
               }
@@ -1589,7 +1536,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
    offset = cfg->arch.reg_save_area_offset;
 
    /*   
-   for (i = 0; i < MONO_MAX_IREGS; ++i)
+   for (i = 0; i < MONO_MAX_VREGS; ++i)
      if (ALPHA_IS_CALLEE_SAVED_REG (i) &&
         (cfg->used_int_regs & (1 << i)) &&
         !( ALPHA_ARGS_REGS & (1 << i)) )
@@ -1675,9 +1622,10 @@ mono_arch_flush_register_windows (void)
 guint32
 mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
 {
+  MonoInst *ins = cfg->varinfo [vmv->idx];
+
    /* FIXME: */
   CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_regalloc_cost");
-  MonoInst *ins = cfg->varinfo [vmv->idx];
 
   if (cfg->method->save_lmf)
     /* The register is already saved */
@@ -1746,7 +1694,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig,
                              MonoJitArgumentInfo *arg_info)
 {
   int k;
-  CallInfo *cinfo = get_call_info (csig, FALSE);
+  CallInfo *cinfo = get_call_info (NULL, csig, FALSE);
   guint32 args_size = cinfo->stack_usage;
 
   ALPHA_DEBUG("mono_arch_get_argument_info");
@@ -1784,11 +1732,11 @@ void
 mono_arch_emit_epilog (MonoCompile *cfg)
 {
   MonoMethod *method = cfg->method;
-  int quad, offset, i;
+  int offset, i;
   unsigned int *code;
   int max_epilog_size = 128;
   int stack_size = cfg->arch.stack_size;
-  CallInfo *cinfo;
+  //  CallInfo *cinfo;
   gint32 lmf_offset = cfg->arch.lmf_offset;
   
   CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_epilog");
@@ -2158,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 +                   \
@@ -2196,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)             \
@@ -2243,9 +2170,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
    
    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);
    
@@ -2255,12 +2179,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
    mono_debug_open_block (cfg, bb, offset);
    
-   ins = bb->code;
-   while (ins)
-     {
+   MONO_BB_FOR_EACH_INS (bb, ins) {
        offset = ((char *)code) - ((char *)cfg->native_code);
          
-       max_len = ((guint8 *)ins_spec [ins->opcode])[MONO_INST_LEN];
+       max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
          
        if (offset > (cfg->code_size - max_len - 16))
         {
@@ -2277,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",
@@ -2304,6 +2228,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl] dreg=%d, sreg1=%d, sreg2=%d\n",
                   ins->dreg, ins->sreg1, ins->sreg2);
            alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_addl_(code, ins->dreg, 0, ins->dreg);
            break;
 
         case OP_ISHL_IMM:
@@ -2312,6 +2237,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl_imm] dreg=%d, sreg1=%d, const=%ld\n",
                   ins->dreg, ins->sreg1, ins->inst_imm);
            alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg);
+          alpha_addl_(code, ins->dreg, 0, ins->dreg);
            break;
 
         case OP_SHL_IMM:
@@ -2365,17 +2291,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            // Shift 32 bit unsigned value right
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shr_un] dreg=%d, sreg1=%d, sreg2=%d\n",
                   ins->dreg, ins->sreg1, ins->sreg2);
-          alpha_zap_(code, ins->sreg1, 0xF0, ins->dreg);
-           alpha_srl(code, ins->dreg, ins->sreg2, ins->dreg);
+          alpha_zap_(code, ins->sreg1, 0xF0, alpha_at /*ins->dreg*/);
+           alpha_srl(code, alpha_at /*ins->dreg*/, ins->sreg2, ins->dreg);
            break;
 
          case OP_ISHR_UN_IMM:
            // Shift 32 bit unassigned value rigth by constant
            g_assert(alpha_is_imm(ins->inst_imm));
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shr_un_imm] dreg=%d, sreg1=%d, const=%ld\n",
-                  ins->dreg, ins->sreg1, ins->inst_imm);
-          alpha_zap_(code, ins->sreg1, 0xF0, ins->dreg);
-           alpha_srl_(code, ins->dreg, ins->inst_imm, ins->dreg);
+                               ins->dreg, ins->sreg1, ins->inst_imm);
+          alpha_zap_(code, ins->sreg1, 0xF0, alpha_at /*ins->dreg*/);
+           alpha_srl_(code, alpha_at /*ins->dreg*/, ins->inst_imm, ins->dreg);
            break;
 
          case OP_LSHR_UN_IMM:
@@ -2872,7 +2798,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Valid only for storing 0
           // storei1_membase_reg will do the rest
           
-          CFG_DEBUG(4) g_printf("ALPHA_CHECK: [storei1_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n",
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei1_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n",
                  ins->inst_imm, ins->inst_destbasereg, ins->inst_offset);
           g_assert(ins->inst_imm == 0);
 
@@ -2912,7 +2838,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Now work only for storing 0
            // For now storei2_membase_reg will do the work
           
-          CFG_DEBUG(4) g_printf("ALPHA_CHECK: [storei2_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n",
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei2_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n",
                  ins->inst_imm, ins->inst_destbasereg, ins->inst_offset);
           
           g_assert(ins->inst_imm == 0);
@@ -3003,14 +2929,16 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Later check different rounding and exc modes
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_add] sreg1=%d, sreg2=%d, dreg=%d\n",
                  ins->sreg1, ins->sreg2, ins->dreg);
-          alpha_addt(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_addt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_trapb(code);
           break;
 
         case OP_FSUB:
           // Later check different rounding and exc modes
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_sub] sreg1=%d, sreg2=%d, dreg=%d\n",
                                 ins->sreg1, ins->sreg2, ins->dreg);
-          alpha_subt(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_subt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_trapb(code);
            break;
 
         case OP_FMUL:
@@ -3148,7 +3076,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            break;
 
          case OP_ALPHA_CMP_IMM_ULE:
-           CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ule] sreg1=%d, const=%0lX, dreg=%\d\n",
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ule] sreg1=%d, const=%0lX, dreg=%d\n",
                   ins->sreg1, ins->inst_imm, ins->dreg);
            alpha_cmpule_(code, ins->sreg1, ins->inst_imm, alpha_at);
            break;
@@ -3179,7 +3107,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
 
          case OP_ALPHA_CMP_IMM_LE:
-           CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_le] sreg1=%d, const=%0lX, dreg=%\d\n",
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_le] sreg1=%d, const=%0lX, dreg=%d\n",
                   ins->sreg1, ins->inst_imm, ins->dreg);
            alpha_cmple_(code, ins->sreg1, ins->inst_imm, alpha_at);
            break;
@@ -3425,6 +3353,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           alpha_ldt(code, ins->dreg, alpha_sp, 0);
           alpha_lda(code, alpha_sp, alpha_sp, 8);
           alpha_cvtqs(code, ins->dreg, ins->dreg);
+          alpha_trapb(code);
           break;
 
          case CEE_CONV_R8:
@@ -3437,13 +3366,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            alpha_ldt(code, ins->dreg, alpha_sp, 0);
            alpha_lda(code, alpha_sp, alpha_sp, 8);
            alpha_cvtqt(code, ins->dreg, ins->dreg);
+          alpha_trapb(code);
            break;
 
         case OP_FCONV_TO_R4:
           // Convert 64 bit float to 32 bit float (T -> S)
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_r4] sreg=%d, dreg=%d\n",
                                 ins->sreg1, ins->dreg);
-          alpha_cvtts(code, ins->sreg1, ins->dreg);
+          alpha_cvtts_su(code, ins->sreg1, ins->dreg);
+          alpha_trapb(code);
           break;
 
         case OP_LOCALLOC:
@@ -3452,11 +3383,33 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // top of stack is used for call params
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [localloc] sreg=%d, dreg=%d\n",
                                ins->sreg1, ins->dreg);
-          alpha_addq_(code, ins->sreg1, (MONO_ARCH_FRAME_ALIGNMENT - 1), ins->sreg1);
-          alpha_and_(code, ins->sreg1, ~(MONO_ARCH_FRAME_ALIGNMENT - 1), ins->sreg1);
+
+          alpha_addq_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1);
+          alpha_bic_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1);
+          if (ins->flags & MONO_INST_INIT)
+              alpha_mov1(code, ins->sreg1, ins->sreg2);
+
           alpha_subq(code, alpha_sp, ins->sreg1, alpha_sp);
-          alpha_lda(code, ins->dreg, alpha_zero, (cfg->arch.params_stack_size));
-          alpha_addq(code, alpha_sp, ins->dreg, ins->dreg);
+          if (cfg->arch.params_stack_size > 0)
+          {
+              alpha_lda(code, ins->dreg, alpha_zero,
+                       (cfg->arch.params_stack_size));
+              alpha_addq(code, alpha_sp, ins->dreg, ins->dreg);
+          }
+          else
+              alpha_mov1(code, alpha_sp, ins->dreg);
+
+          if (ins->flags & MONO_INST_INIT)
+          {
+               // TODO: Optimize it later
+               alpha_lda(code, ins->sreg2, ins->sreg2,
+                       -(MONO_ARCH_LOCALLOC_ALIGNMENT));
+               alpha_blt(code, ins->sreg2, 3);
+               alpha_addq(code, ins->sreg2, ins->dreg, alpha_at);
+               alpha_stq(code, alpha_zero, alpha_at, 0);
+               alpha_br(code, alpha_zero, -5);
+          }
+
           break;
 
         case OP_MOVE:
@@ -3568,6 +3521,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
            break;
 
+        case OP_FBGE:
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbge] [");
+          alpha_fbne(code, (alpha_at+1), 1);
+          EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
+           break;
+
          case OP_FBLE_UN:
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble_un] [");
            alpha_fbeq(code, (alpha_at+1), 1);
@@ -3575,6 +3534,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
            break;
 
+         case OP_FBLE:
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble] [");
+           alpha_fbne(code, (alpha_at+1), 1);
+           EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
+           break;
+
          case OP_FBLT_UN:
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt_un] [");
            alpha_fbeq(code, (alpha_at+1), 1);
@@ -3582,6 +3547,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
            break;
 
+         case OP_FBLT:
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt] [");
+           alpha_fbne(code, (alpha_at+1), 1);
+           EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
+           break;
+
          case OP_FBGT_UN:
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt_un] [");
            alpha_fbeq(code, (alpha_at+1), 1);
@@ -3589,6 +3560,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
            break;
 
+         case OP_FBGT:
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt] [");
+           alpha_fbne(code, (alpha_at+1), 1);
+           EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
+           break;
+
         case OP_IBEQ:
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [ibeq] [");
           EMIT_ALPHA_BRANCH(ins, alpha_at, beq);
@@ -3614,55 +3591,33 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           ins->inst_c0 = (char *)code - (char *)cfg->native_code;
           break;
           
-        case CEE_BR:
+        case OP_BR:
           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->flags & MONO_INST_BRLABEL)
+          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;
@@ -3678,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;
           
@@ -3772,7 +3727,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
             // of by call_filter. There should be difference. For now just
             // handle - call_handler
 
-            CFG_DEBUG(4) g_print("ALPHA_CHECK: [start_handler] basereg=%d, offset=%0x\n",
+            CFG_DEBUG(4) g_print("ALPHA_CHECK: [start_handler] basereg=%d, offset=%0lx\n",
                ins->inst_left->inst_basereg, ins->inst_left->inst_offset);
 
             alpha_stq(code, alpha_ra, ins->inst_left->inst_basereg, 
@@ -3780,10 +3735,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           }
           break;
 
-        case CEE_ENDFINALLY:
+        case OP_ENDFINALLY:
           {
              // Keep in sync with start_handler
-             CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfinally] basereg=%d, offset=%0x\n",
+             CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfinally] basereg=%d, offset=%0lx\n",
                 ins->inst_left->inst_basereg, ins->inst_left->inst_offset);
 
              alpha_ldq(code, alpha_ra, ins->inst_left->inst_basereg,
@@ -3796,7 +3751,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
         case OP_ENDFILTER:
           {
             // Keep in sync with start_handler
-            CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfilter] sreg1=%d, basereg=%d, offset=%0x\n",
+            CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfilter] sreg1=%d, basereg=%d, offset=%0lx\n",
                ins->sreg1, ins->inst_left->inst_basereg, ins->inst_left->inst_offset);
 
             alpha_ldq(code, alpha_ra, ins->inst_left->inst_basereg,
@@ -3824,15 +3779,9 @@ 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 CEE_THROW:
-          CFG_DEBUG(4) g_print("ALPHA_CHECK: [throw] sreg1=%0lx\n",
+        case OP_THROW:
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [throw] sreg1=%0x\n",
                                ins->sreg1);
           alpha_mov1(code, ins->sreg1, alpha_a0);
           code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD,
@@ -3840,23 +3789,24 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           break;
 
          case OP_RETHROW:
-           CFG_DEBUG(4) g_print("ALPHA_CHECK: [rethrow] sreg1=%0lx\n",
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [rethrow] sreg1=%0x\n",
                                 ins->sreg1);
            alpha_mov1(code, ins->sreg1, alpha_a0);
            code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD,
                              (gpointer)"mono_arch_rethrow_exception");
            break;
 
-        case CEE_JMP:
+        case OP_JMP:
           {
-            CFG_DEBUG(4) g_print("ALPHA_CHECK: [jmp] %p\n", ins->inst_p0);
             /*
-             * Note: this 'frame destruction' logic is useful for tail calls, too.
-             * Keep in sync with the code in emit_epilog.
+             * Note: this 'frame destruction' logic is useful for tail calls,
+             too. Keep in sync with the code in emit_epilog.
              */
-            int pos = 0, i, offset;
+            int offset;
             AlphaGotData ge_data;
 
+            CFG_DEBUG(4) g_print("ALPHA_CHECK: [jmp] %p\n", ins->inst_p0);
+
             /* FIXME: no tracing support... */
             if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
               code = mono_arch_instrument_epilog (cfg,
@@ -3887,7 +3837,56 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           mono_add_patch_info (cfg, offset,
                                (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
           break;
-          
+
+        case OP_MEMORY_BARRIER:
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [mb]\n");
+          alpha_mb(code);
+          break;
+         
+        case OP_CKFINITE:
+          // Float register contains a value which we need to check
+          {
+               double  ni = -1.0 / 0.0;
+               double  pi = 1.0 / 0.0;
+               AlphaGotData    ge_data;
+
+               CFG_DEBUG(4) g_print("ALPHA_TODO: [chfinite] sreg1=%d\n", ins->sreg1);
+               alpha_cmptun_su(code, ins->sreg1, ins->sreg1, alpha_at);
+               alpha_trapb(code);
+               EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+
+               // Negative infinity
+               ge_data.data.d = ni;
+               add_got_entry(cfg, GT_DOUBLE, ge_data,
+                           (char *)code - (char *)cfg->native_code,
+                           MONO_PATCH_INFO_NONE, 0);
+               alpha_ldt(code, alpha_at, alpha_gp, 0);
+
+               alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at);
+               alpha_trapb(code);
+
+               EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+
+                // Positive infinity
+                ge_data.data.d = pi;
+                add_got_entry(cfg, GT_DOUBLE, ge_data,
+                           (char *)code - (char *)cfg->native_code,
+                           MONO_PATCH_INFO_NONE, 0);
+                alpha_ldt(code, alpha_at, alpha_gp, 0);
+
+                alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at);
+                alpha_trapb(code);
+
+                EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+          }
+          break;
+        case OP_FDIV:
+          CFG_DEBUG(4) g_print("ALPHA_TODO: [fdiv] dest=%d, sreg1=%d, sreg2=%d\n",
+               ins->dreg, ins->sreg1, ins->sreg2);
+          alpha_divt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_trapb(code);
+
+          break;
         default:
           g_warning ("unknown opcode %s in %s()\n",
                      mono_inst_name (ins->opcode), __FUNCTION__);
@@ -3910,9 +3909,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        
        last_ins = ins;
        last_offset = offset;
-       
-       ins = ins->next;          
-     }
+   }
    
    cfg->code_len = ((char *)code) - ((char *)cfg->native_code);
 }
@@ -4038,7 +4035,7 @@ mono_arch_fregname (int reg) {
 
 void
 mono_arch_patch_code (MonoMethod *method, MonoDomain *domain,
-                      guint8 *code, MonoJumpInfo *ji, gboolean run_cctors)
+                      guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
 {
   MonoJumpInfo *patch_info;
   gboolean compile_aot = !run_cctors;
@@ -4074,7 +4071,7 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain,
 
        case MONO_PATCH_INFO_GOT_OFFSET:
          {
-           unsigned int *ip2 = ip;
+           unsigned int *ip2 = (unsigned int *)ip;
            unsigned int inst = *ip2;
            unsigned int off = patch_info->data.offset & 0xFFFFFFFF;
 
@@ -4089,12 +4086,12 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain,
        case MONO_PATCH_INFO_CLASS_INIT: 
          {               
            /* Might already been changed to a nop */
-           unsigned int* ip2 = ip;
+           unsigned int* ip2 = (unsigned int *)ip;
           unsigned long t_addr = (unsigned long)target;
  
            if (*ip2 != (t_addr & 0xFFFFFFFF) ||
                *(ip2+1) != ((t_addr>>32) & 0xFFFFFFFF))
-                   NOT_IMPLEMENTED("mono_arch_patch_code: MONO_PATCH_INFO_CLASS_INIT");
+                       NOT_IMPLEMENTED;
            //  amd64_call_code (ip2, 0);
            break;
          }
@@ -4213,7 +4210,7 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst,
        int this_reg, int this_type, int vt_reg)
 {
   MonoCallInst *call = (MonoCallInst*)inst;
-  CallInfo * cinfo = get_call_info (inst->signature, FALSE);
+  CallInfo * cinfo = get_call_info (cfg->generic_sharing_context, inst->signature, FALSE);
 
   CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_this_vret_args");
 
@@ -4240,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,
@@ -4255,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,
@@ -4339,6 +4336,21 @@ mono_arch_cpu_init (void)
   //printf("amask: %x, implver: %x", amask, implver);
 }
 
+/*
+ * Initialize architecture specific code.
+ */
+void
+mono_arch_init (void)
+{
+}
+
+/*
+ * Cleanup architecture specific code.
+ */
+void
+mono_arch_cleanup (void)
+{
+}
 
 /*
  * get_call_info:
@@ -4351,7 +4363,7 @@ mono_arch_cpu_init (void)
  * For x86 win32, see ???.
  */
 static CallInfo*
-get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke)
 {
    guint32 i, gr, fr, *pgr, *pfr;
    MonoType *ret_type;
@@ -4410,7 +4422,7 @@ get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
        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;
@@ -4421,7 +4433,7 @@ get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
        {
         guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
                        
-        add_valuetype (sig, &cinfo->ret, sig->ret, TRUE,
+        add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE,
                        &tmp_gr, &tmp_fr, &tmp_stacksize);
         
         if (cinfo->ret.storage == ArgOnStack)
@@ -4513,7 +4525,7 @@ get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
         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;
@@ -4522,7 +4534,7 @@ get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
        case MONO_TYPE_VALUETYPE:
         /* FIXME: */
         /* We allways pass valuetypes on the stack */
-        add_valuetype (sig, ainfo, sig->params [i],
+        add_valuetype (gsctx, sig, ainfo, sig->params [i],
                        FALSE, pgr, pfr, &stack_size);
         break;
        case MONO_TYPE_TYPEDBYREF:
@@ -4680,7 +4692,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
    n = sig->param_count + sig->hasthis;
 
    // Collect info about method we age going to call
-   cinfo = get_call_info (sig, sig->pinvoke);
+   cinfo = get_call_info (cfg->generic_sharing_context, sig, sig->pinvoke);
 
    CFG_DEBUG(3) g_print("ALPHA: Will call %s method with %d(%d) params. RetType: %s(0x%X)\n",
                        sig->pinvoke ? "PInvoke" : "Managed",
@@ -4761,7 +4773,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
         if ((i >= sig->hasthis) &&
             (MONO_TYPE_ISSTRUCT(arg_type)))
           {
-            gint align;
+            guint align;
             guint32 size;
             
             if (arg_type->type == MONO_TYPE_TYPEDBYREF) {
@@ -4773,7 +4785,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                 size = mono_type_native_stack_size (&in->klass->byval_arg,
                                                     &align);
               else
-                size = mono_type_stack_size (&in->klass->byval_arg, &align);
+                size = mini_type_stack_size (cfg->generic_sharing_context, &in->klass->byval_arg, &align);
 
             if (ainfo->storage == ArgAggregate)
               {
@@ -4976,19 +4988,6 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
 
 /*========================= End of Function ========================*/
 
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name         - mono_arch_break                                   */
-/*                                                                  */
-/* Function     - Process a "break" operation for debugging.        */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-static void
-mono_arch_break(void) {
-}
-
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name         - mono_arch_register_lowlevel_calls                 */
@@ -5002,7 +5001,6 @@ mono_arch_register_lowlevel_calls (void)
 {
    ALPHA_DEBUG("mono_arch_register_lowlevel_calls");
    
-   mono_register_jit_icall (mono_arch_break, "mono_arch_break", NULL, TRUE);
    mono_register_jit_icall (mono_arch_get_lmf_addr, "mono_arch_get_lmf_addr",
                                                        NULL, TRUE);
 }
@@ -5036,42 +5034,6 @@ mono_arch_get_global_int_regs (MonoCompile *cfg)
 
 /*========================= End of Function ========================*/
 
-static gboolean
-is_regsize_var (MonoType *t)
-{
-  if (t->byref)
-    return TRUE;
-
-  t = mono_type_get_underlying_type (t);
-  switch (t->type) {
-  case MONO_TYPE_I1:
-  case MONO_TYPE_U1:
-  case MONO_TYPE_I2:
-  case MONO_TYPE_U2:
-  case MONO_TYPE_I4:
-  case MONO_TYPE_U4:
-  case MONO_TYPE_I:
-  case MONO_TYPE_U:
-  case MONO_TYPE_PTR:
-  case MONO_TYPE_FNPTR:
-  case MONO_TYPE_BOOLEAN:
-    return TRUE;
-  case MONO_TYPE_OBJECT:
-  case MONO_TYPE_STRING:
-  case MONO_TYPE_CLASS:
-  case MONO_TYPE_SZARRAY:
-  case MONO_TYPE_ARRAY:
-    return TRUE;
-  case MONO_TYPE_VALUETYPE:
-    return FALSE;
-  }
-
-  return FALSE;
-}
-
-
-
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name         - mono_arch_get_allocatable_int_vars                */
@@ -5091,15 +5053,15 @@ 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);
 
-   cinfo = get_call_info (sig, FALSE);
+   cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
 
    for (i = 0; i < sig->param_count + sig->hasthis; ++i)
      {
-       MonoInst *ins = cfg->varinfo [i];
+       MonoInst *ins = cfg->args [i];
 
        ArgInfo *ainfo = &cinfo->args [i];
 
@@ -5128,7 +5090,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
           (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG))
         continue;
 
-       if (is_regsize_var (ins->inst_vtype))
+       if (mono_is_regsize_var (ins->inst_vtype))
         {
           g_assert (MONO_VARINFO (cfg, i)->reg == -1);
           g_assert (i == vmv->idx);
@@ -5168,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                   */
@@ -5212,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;
 }
 
@@ -5243,7 +5175,7 @@ mono_arch_create_class_init_trampoline (MonoVTable *vtable)
 {
    ALPHA_DEBUG("mono_arch_create_class_init_trampoline");
    
-   NOT_IMPLEMENTED("mono_arch_create_class_init_trampoline: check MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE define");
+   NOT_IMPLEMENTED;
    
    return 0;
 }
@@ -5277,7 +5209,7 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
       /* Allocate a new area on the stack and save arguments there */
       sig = mono_method_signature (cfg->method);
 
-      cinfo = get_call_info (sig, FALSE);
+      cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
 
       n = sig->param_count + sig->hasthis;
 
@@ -5289,7 +5221,7 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
       
       for (i = 0; i < n; ++i)
        {
-         inst = cfg->varinfo [i];
+         inst = cfg->args [i];
 
          if (inst->opcode == OP_REGVAR)
            {
@@ -5358,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;
@@ -5522,11 +5453,11 @@ 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);
    
-   cinfo = get_call_info (sig, FALSE);
+   cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
    
    /* if (cfg->arch.omit_fp) {
       cfg->flags |= MONO_CFG_HAS_SPILLUP;
@@ -5653,8 +5584,6 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        }
      }
    
-   g_free (offsets);
-
    // TODO check how offsets[i] are calculated
    // it seems they are points to the end on data. Like 8, but it actually - 0
 
@@ -5709,7 +5638,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
    // Reserve space for method params
    for (i = 0; i < sig->param_count + sig->hasthis; ++i)
      {
-       inst = cfg->varinfo [i];
+       inst = cfg->args [i];
 
        if (inst->opcode != OP_REGVAR)
         {
@@ -5771,7 +5700,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
               break;
 
             default:
-              NOT_IMPLEMENTED("");
+              NOT_IMPLEMENTED;
             }
 
           if (!inreg && (ainfo->storage != ArgOnStack))
@@ -5852,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;
@@ -5862,19 +5791,20 @@ mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
          pc, regs);
 
   // Check if we have parameters on stack
-  if (pc[-2] & 0xFFFF0000 == 0x23DE0000)     // lda     sp,-n(sp)
+  if ((pc[-2] & 0xFFFF0000) == 0x23DE0000)     // lda     sp,-n(sp)
     start_index = -3;
 
   // Check for (call_membase):
   // -4: mov     v0,a0        - load this ???
-  // -3: ldq     v0,0(v0)     - load vtable
+  // -3: ldq     v0,0(v0)     - load vtable 
   // -2: ldq     t12,64(v0)   - load method (object->vtable->vtable[method->slot])
-  if ((pc[start_index-1] & 0xFFFFFFFF) == 0xA4000000 &&
+  if ((pc[start_index-1] & 0xFC00FFFF) == 0xA4000000 &&
       (pc[start_index] & 0xFFFF0000) == 0xA7600000
       )
     {
       disp = pc[start_index] & 0xFFFF;
-      reg = 0; // For now
+      reg = (pc[start_index-1] >> AXP_REG1_SHIFT) & AXP_REG_MASK;
+      //reg = 0; // For now
 
       ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_vcall_slot_addr callvirt] call_membase");
 
@@ -5886,7 +5816,7 @@ mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
   // -4: ldq     v0,0(v0)
   // -3: ldq     v0,-n(v0)
   // -2: ldq     t12,0(v0)
-  if ((pc[start_index-2] & 0xFFFFFFFF) == 0xA4000000 &&
+  if ((pc[start_index-2] & 0xFC00FFFF) == 0xA4000000 &&
       (pc[start_index-1] & 0xFFFF0000) == 0xA4000000 &&
       (pc[start_index] & 0xFFFF0000) == 0xA7600000
       )
@@ -5902,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 ();
+}