2007-08-30 Jonathan Chambers <joncham@gmail.com>
[mono.git] / mono / mini / mini-alpha.c
index 9eb5cac89f55445791a0255566b2f48533513a40..06c2f4a4f638aaedd21fde7e4b8bb1e8d3a981cb 100644 (file)
@@ -82,8 +82,7 @@
 static int indent_level = 0;
 
 int mini_alpha_verbose_level = 0;
-
-static const char*const * ins_spec = alpha_desc;
+static int bwx_supported = 0;
 
 static gboolean tls_offset_inited = FALSE;
 
@@ -200,11 +199,11 @@ add_valuetype (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)
@@ -446,6 +445,8 @@ static void
   MonoInst *ins, *last_ins = NULL;
   ins = bb->code;
    
+  CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE pass\n");
+
   while (ins) 
     {  
       switch (ins->opcode) 
@@ -506,6 +507,7 @@ static void
          break;
 
        case OP_LOADI8_MEMBASE:
+       case OP_LOAD_MEMBASE:
           /*
            * Note: if reg1 = reg2 the load op is removed
            *
@@ -515,7 +517,9 @@ static void
            * OP_STOREI8_MEMBASE_REG reg1, offset(basereg)
            * OP_MOVE reg1, reg2
            */
-          if (last_ins && (last_ins->opcode == OP_STOREI8_MEMBASE_REG) &&
+          if (last_ins &&
+             (last_ins->opcode == OP_STOREI8_MEMBASE_REG ||
+               last_ins->opcode == OP_STORE_MEMBASE_REG) &&
               ins->inst_basereg == last_ins->inst_destbasereg &&
               ins->inst_offset == last_ins->inst_offset)
             {
@@ -950,10 +954,8 @@ static void
    
    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;
+   if (bb->max_vreg > cfg->rs->next_vreg)
+        cfg->rs->next_vreg = bb->max_vreg;
    
    /*
     * FIXME: Need to add more instructions, but the current machine
@@ -1048,22 +1050,6 @@ static void
 
            break;
 
-          /*
-            case OP_LOAD_MEMBASE:
-            case OP_LOADI8_MEMBASE:
-            if (!amd64_is_imm32 (ins->inst_offset)) 
-            {
-            
-            NEW_INS (cfg, temp, OP_I8CONST);
-            temp->inst_c0 = ins->inst_offset;
-            temp->dreg = mono_regstate_next_int (cfg->rs);
-            ins->opcode = OP_AMD64_LOADI8_MEMINDEX;
-            ins->inst_indexreg = temp->dreg;
-            }
-                        
-            break;
-          */
-
         case OP_STORE_MEMBASE_IMM:
         case OP_STOREI8_MEMBASE_IMM:
           if (ins->inst_imm != 0) 
@@ -1089,6 +1075,7 @@ static void
           break;
 
          case OP_STOREI1_MEMBASE_IMM:
+          if (ins->inst_imm != 0 || !bwx_supported)
              {
                MonoInst *temp;
                NEW_INS (cfg, temp, OP_ICONST);
@@ -1100,6 +1087,7 @@ static void
            break;
 
          case OP_STOREI2_MEMBASE_IMM:
+           if (ins->inst_imm != 0 || !bwx_supported)
           {
             MonoInst *temp;
             NEW_INS (cfg, temp, OP_ICONST);
@@ -1199,6 +1187,19 @@ static void
               ins->sreg2 = temp->dreg;
               ins->opcode = OP_LSHR;
             }
+          break;
+         case OP_LSHL_IMM:
+           if (!alpha_is_imm(ins->inst_imm))
+             {
+               MonoInst *temp;
+               NEW_INS(cfg, temp, OP_ICONST);
+               temp->inst_c0 = ins->inst_imm;
+               temp->dreg = mono_regstate_next_int(cfg->rs);
+               ins->sreg2 = temp->dreg;
+               ins->opcode = OP_LSHL;
+             }
+           break;
+
         default:
           break;
         }
@@ -1209,8 +1210,7 @@ static void
    
    bb->last_ins = last_ins;
    
-   bb->max_ireg = cfg->rs->next_vireg;
-   bb->max_freg = cfg->rs->next_vfreg;
+   bb->max_vreg = cfg->rs->next_vreg;
 }
 
 /*------------------------------------------------------------------*/
@@ -1355,7 +1355,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)
        {
@@ -1482,8 +1482,21 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        // Save method
        alpha_stq(code, alpha_pv, alpha_fp,
                  (lmf_offset + G_STRUCT_OFFSET(MonoLMF, method)));
-
      }
+
+   /* Save (global) regs */
+   offset = cfg->arch.reg_save_area_offset;
+
+   for (i = 0; i < MONO_MAX_IREGS; ++i)
+     if (ALPHA_IS_CALLEE_SAVED_REG (i) &&
+         (cfg->used_int_regs & (1 << i)) &&
+         !( ALPHA_ARGS_REGS & (1 << i)) )
+       {
+         alpha_stq(code, i, alpha_fp, offset);
+         CFG_DEBUG(3) g_print("ALPHA: Saved caller reg %d at offset: %0x\n",
+                             i, offset);
+         offset += 8;
+       }
    
    offset = cfg->arch.args_save_area_offset;
 
@@ -1504,32 +1517,47 @@ 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)
         {
         case ArgInIReg:
           // We need to save all used a0-a5 params
-          //for (i=0; i<PARAM_REGS; i++)
-          //  {
-          //    if (i < cinfo->reg_usage)
           {
-            //alpha_stq(code, ainfo->reg, alpha_fp, offset);
-            alpha_stq(code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
+            if (inst->opcode == OP_REGVAR)
+              {
+                alpha_mov1(code, ainfo->reg, inst->dreg);
+                CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d in reg %d\n",
+                                     ainfo->reg, inst->dreg);
+              }
+            else
+              {
+                alpha_stq(code, ainfo->reg, inst->inst_basereg,
+                          inst->inst_offset);
                   
-            CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d at offset: %0lx\n",
-                                 ainfo->reg, inst->inst_offset/*offset*/);
+                CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d at offset: %0lx\n",
+                                     ainfo->reg, inst->inst_offset);
                   
-            offset += 8;
+                offset += 8;
+              }
+          }
+          break;
+        case ArgAggregate:
+          {
+            for(j=0; j<ainfo->nregs; j++)
+              {
+                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,
+                          (inst->inst_offset + (8*j)));
+                offset += 8;
+              }
           }
-          //}
           break;
         case ArgInDoubleReg:
         case ArgInFloatReg:
           // We need to save all used af0-af5 params
-          //for (i=0; i<PARAM_REGS; i++)
-          //  {
-          //    if (i < cinfo->freg_usage)
           {
             switch(cinfo->args[i].storage)
               {
@@ -1554,8 +1582,9 @@ 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)) )
@@ -1565,7 +1594,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                i, offset);
         offset += 8;
        }
-
+   */
    // TODO - check amd64 code for "Might need to attach the thread to the JIT"
 
    if (method->save_lmf)
@@ -1641,10 +1670,18 @@ 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");
 
-  return 2;
+  if (cfg->method->save_lmf)
+    /* The register is already saved */
+    /* substract 1 for the invisible store in the prolog */
+    return (ins->opcode == OP_ARG) ? 1 : 0;
+  else
+    /* push+pop */
+    return (ins->opcode == OP_ARG) ? 2 : 1;
 }
 
 /*========================= End of Function ========================*/
@@ -1743,11 +1780,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");
@@ -2219,7 +2256,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
      {
        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))
         {
@@ -2240,15 +2277,22 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Shift 64 bit value right
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr] dreg=%d, sreg1=%d, sreg2=%d\n",
                  ins->dreg, ins->sreg1, ins->sreg2);
-          alpha_srl(code, ins->sreg1, ins->sreg2, ins->dreg);
+          alpha_sra(code, ins->sreg1, ins->sreg2, ins->dreg);
           break;
 
+       case OP_LSHR_UN:
+          // Shift 64 bit value right
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr_un] dreg=%d, sreg1=%d, sreg2=%d\n",
+                  ins->dreg, ins->sreg1, ins->sreg2);
+           alpha_srl(code, ins->sreg1, ins->sreg2, ins->dreg);
+           break;
+
         case OP_LSHR_IMM:
           // Shift 64 bit value right by constant
           g_assert(alpha_is_imm(ins->inst_imm));
-          CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr] dreg=%d, sreg1=%d, const=%ld\n",
+          CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr_imm] dreg=%d, sreg1=%d, const=%ld\n",
                  ins->dreg, ins->sreg1, ins->inst_imm);
-          alpha_srl_(code, ins->sreg1, ins->inst_imm, ins->dreg);
+          alpha_sra_(code, ins->sreg1, ins->inst_imm, ins->dreg);
           break;
 
         case OP_ISHL:
@@ -2256,6 +2300,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:
@@ -2264,6 +2309,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:
@@ -2273,6 +2319,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg);
            break;
 
+         case OP_LSHL_IMM:
+           g_assert(alpha_is_imm(ins->inst_imm));
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_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);
+           break;
+
+
         case CEE_SHL:
            // Shift 32 bit value left
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [shl] dreg=%d, sreg1=%d, sreg2=%d\n",
@@ -2280,6 +2334,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg);
            break;
 
+         case OP_LSHL:
+           // Shift 64 bit value left
+           CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shl] dreg=%d, sreg1=%d, sreg2=%d\n",
+                  ins->dreg, ins->sreg1, ins->sreg2);
+           alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg);
+           break;
+
 
          case OP_ISHR:
            // Shift 32 bit value right
@@ -2302,17 +2363,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:
@@ -2709,10 +2770,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Load unassigned byte from REGOFFSET
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadu1_membase] dreg=%d, basereg=%d, offset=%0lx\n",
                  ins->dreg, ins->inst_basereg, ins->inst_offset);
-
-          alpha_ldq_u(code, alpha_r25, ins->inst_basereg, ins->inst_offset);
-          alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset);
-          alpha_extbl(code, alpha_r25, alpha_at, ins->dreg);
+          if (bwx_supported)
+            alpha_ldbu(code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+          else
+            {
+              alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
+                          ins->inst_offset);
+              alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset);
+              alpha_extbl(code, alpha_r25, alpha_at, ins->dreg);
+            }
           break;
           
         case OP_LOADU2_MEMBASE:
@@ -2720,14 +2786,19 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadu2_membase] dreg=%d, basereg=%d, offset=%0lx\n",
                  ins->dreg, ins->inst_basereg, ins->inst_offset);
 
-           alpha_ldq_u(code, alpha_r24, ins->inst_basereg, ins->inst_offset);
-          alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
-                      (ins->inst_offset+1));
-           alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset);
-           alpha_extwl(code, alpha_r24, alpha_at, ins->dreg);
-          alpha_extwh(code, alpha_r25, alpha_at, alpha_r25);
-          alpha_bis(code, alpha_r25, ins->dreg, ins->dreg);
-
+          if (bwx_supported)
+            alpha_ldwu(code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+          else
+            {
+              alpha_ldq_u(code, alpha_r24, ins->inst_basereg,
+                          ins->inst_offset);
+              alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
+                          (ins->inst_offset+1));
+              alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset);
+              alpha_extwl(code, alpha_r24, alpha_at, ins->dreg);
+              alpha_extwh(code, alpha_r25, alpha_at, alpha_r25);
+              alpha_bis(code, alpha_r25, ins->dreg, ins->dreg);
+            }
           break;
           
         case OP_LOAD_MEMBASE:
@@ -2752,71 +2823,104 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Load sign-extended byte from REGOFFSET
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi1_membase] dreg=%d, basereg=%d, offset=%0lx\n",
                  ins->dreg, ins->inst_basereg, ins->inst_offset);
-          alpha_ldq_u(code, alpha_r25, ins->inst_basereg, ins->inst_offset);
-          alpha_lda(code, alpha_at, ins->inst_basereg, (ins->inst_offset+1));
-          alpha_extqh(code, alpha_r25, alpha_at, ins->dreg);
-          alpha_sra_(code, ins->dreg, 56, ins->dreg);
+          if (bwx_supported)
+            {
+              alpha_ldbu(code, ins->dreg, ins->inst_basereg,
+                         ins->inst_offset);
+              alpha_sextb(code, ins->dreg, ins->dreg);
+            }
+          else
+            {
+              alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
+                          ins->inst_offset);
+              alpha_lda(code, alpha_at, ins->inst_basereg,
+                        (ins->inst_offset+1));
+              alpha_extqh(code, alpha_r25, alpha_at, ins->dreg);
+              alpha_sra_(code, ins->dreg, 56, ins->dreg);
+            }
           break;
           
         case OP_LOADI2_MEMBASE:
           // Load sign-extended word from REGOFFSET
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi2_membase] dreg=%d, basereg=%d, offset=%0lx\n",
                  ins->dreg, ins->inst_basereg, ins->inst_offset);
-           alpha_ldq_u(code, alpha_r24, ins->inst_basereg, ins->inst_offset);
-           alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
-                      (ins->inst_offset+1));
-           alpha_lda(code, alpha_at, ins->inst_basereg, (ins->inst_offset+2));
-           alpha_extql(code, alpha_r24, alpha_at, ins->dreg);
-           alpha_extqh(code, alpha_r25, alpha_at, alpha_r25);
-           alpha_bis(code, alpha_r25, ins->dreg, ins->dreg);
-          alpha_sra_(code, ins->dreg, 48, ins->dreg);
-          
+          if (bwx_supported)
+            {
+              alpha_ldwu(code, ins->dreg, ins->inst_basereg,
+                         ins->inst_offset);
+              alpha_sextw(code, ins->dreg, ins->dreg);
+            }
+          else
+            {
+              alpha_ldq_u(code, alpha_r24, ins->inst_basereg,
+                          ins->inst_offset);
+              alpha_ldq_u(code, alpha_r25, ins->inst_basereg,
+                          (ins->inst_offset+1));
+              alpha_lda(code, alpha_at, ins->inst_basereg,
+                        (ins->inst_offset+2));
+              alpha_extql(code, alpha_r24, alpha_at, ins->dreg);
+              alpha_extqh(code, alpha_r25, alpha_at, alpha_r25);
+              alpha_bis(code, alpha_r25, ins->dreg, ins->dreg);
+              alpha_sra_(code, ins->dreg, 48, ins->dreg);
+            }
           break;                        
           
         case OP_STOREI1_MEMBASE_IMM:
           // Store signed byte at REGOFFSET
-          // For now storei1_membase_reg will do the work
-          g_assert_not_reached();
-          /*
-          printf("ALPHA_TODO: [storei1_membase_imm] const=%0lx, destbasereg=%d, offset=%0lx\n",
+          // Valid only for storing 0
+          // storei1_membase_reg will do the rest
+          
+          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(alpha_is_imm(ins->inst_imm));
+          g_assert(ins->inst_imm == 0);
 
-          alpha_lda(code, alpha_r25, alpha_zero, ins->inst_imm);
+          if (bwx_supported)
+               alpha_stb(code, alpha_zero, ins->inst_destbasereg,
+                       ins->inst_offset);
+          else
+               g_assert_not_reached();
 
-          alpha_lda(code, alpha_at, ins->inst_destbasereg, ins->inst_offset);
-          alpha_ldq_u(code, alpha_r24, ins->inst_destbasereg, ins->inst_offset);
-          alpha_insbl(code, alpha_r25, alpha_at, alpha_r23);
-          alpha_mskbl(code, alpha_r24, alpha_at, alpha_r24);
-          alpha_bis(code, alpha_r24, alpha_r23, alpha_r24);
-          alpha_stq_u(code, alpha_r24, ins->inst_destbasereg, ins->inst_offset);
-          */
           break;
 
         case OP_STOREI1_MEMBASE_REG:
           // Store byte at REGOFFSET
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei1_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n",
                  ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
-
-           alpha_lda(code, alpha_at, ins->inst_destbasereg, ins->inst_offset);
-           alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg,
-                      ins->inst_offset);
-           alpha_insbl(code, ins->sreg1, alpha_at, alpha_r24);
-           alpha_mskbl(code, alpha_r25, alpha_at, alpha_r25);
-           alpha_bis(code, alpha_r25, alpha_r24, alpha_r25);
-           alpha_stq_u(code, alpha_r25, ins->inst_destbasereg,
-                      ins->inst_offset);
-
+          if (bwx_supported)
+            {
+              alpha_stb(code, ins->sreg1, ins->inst_destbasereg,
+                        ins->inst_offset);
+            }
+          else
+            {
+              alpha_lda(code, alpha_at, ins->inst_destbasereg,
+                        ins->inst_offset);
+              alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg,
+                          ins->inst_offset);
+              alpha_insbl(code, ins->sreg1, alpha_at, alpha_r24);
+              alpha_mskbl(code, alpha_r25, alpha_at, alpha_r25);
+              alpha_bis(code, alpha_r25, alpha_r24, alpha_r25);
+              alpha_stq_u(code, alpha_r25, ins->inst_destbasereg,
+                          ins->inst_offset);
+            }
           break;
           
         case OP_STOREI2_MEMBASE_IMM:
            // Store signed word at REGOFFSET
+          // Now work only for storing 0
            // For now storei2_membase_reg will do the work
-           g_assert_not_reached();
-          /*
-          printf("ALPHA_TODO: [storei2_membase_imm] 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);
+          
+          if (bwx_supported)
+               alpha_stw(code, alpha_zero, ins->inst_destbasereg,
+                       ins->inst_offset);
+          else
+               g_assert_not_reached();
+
           break;
           
         case OP_STOREI2_MEMBASE_REG:
@@ -2824,21 +2928,30 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
            CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei2_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n",
                   ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
           
-          alpha_lda(code, alpha_at, ins->inst_destbasereg, ins->inst_offset);
-          alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg,
-                      (ins->inst_offset+1));
-          alpha_ldq_u(code, alpha_r24, ins->inst_destbasereg,
-                      ins->inst_offset);
-          alpha_inswh(code, ins->sreg1, alpha_at, alpha_r23);
-          alpha_inswl(code, ins->sreg1, alpha_at, alpha_r22);
-          alpha_mskwh(code, alpha_r25, alpha_at, alpha_r25);
-          alpha_mskwl(code, alpha_r24, alpha_at, alpha_r24);
-          alpha_bis(code, alpha_r25, alpha_r23, alpha_r25);
-          alpha_bis(code, alpha_r24, alpha_r22, alpha_r24);
-          alpha_stq_u(code, alpha_r25, ins->inst_destbasereg,
-                      (ins->inst_offset+1));
-          alpha_stq_u(code, alpha_r24, ins->inst_destbasereg,
-                       ins->inst_offset);
+          if (bwx_supported)
+            {
+              alpha_stw(code, ins->sreg1, ins->inst_destbasereg,
+                        ins->inst_offset);
+            }
+          else
+            {
+              alpha_lda(code, alpha_at, ins->inst_destbasereg,
+                        ins->inst_offset);
+              alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg,
+                          (ins->inst_offset+1));
+              alpha_ldq_u(code, alpha_r24, ins->inst_destbasereg,
+                          ins->inst_offset);
+              alpha_inswh(code, ins->sreg1, alpha_at, alpha_r23);
+              alpha_inswl(code, ins->sreg1, alpha_at, alpha_r22);
+              alpha_mskwh(code, alpha_r25, alpha_at, alpha_r25);
+              alpha_mskwl(code, alpha_r24, alpha_at, alpha_r24);
+              alpha_bis(code, alpha_r25, alpha_r23, alpha_r25);
+              alpha_bis(code, alpha_r24, alpha_r22, alpha_r24);
+              alpha_stq_u(code, alpha_r25, ins->inst_destbasereg,
+                          (ins->inst_offset+1));
+              alpha_stq_u(code, alpha_r24, ins->inst_destbasereg,
+                          ins->inst_offset);
+            }
 
           break;
           
@@ -2888,14 +3001,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:
@@ -3033,7 +3148,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;
@@ -3064,7 +3179,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;
@@ -3164,18 +3279,28 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           // Read about sextb
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i1] sreg=%d, dreg=%d\n",
                  ins->sreg1, ins->dreg);
-           alpha_sll_(code, ins->sreg1, 24, alpha_at);
-           alpha_addl(code, alpha_at, alpha_zero, ins->dreg);
-           alpha_sra_(code, ins->dreg, 24, ins->dreg);
+          if (bwx_supported)
+            alpha_sextb(code, ins->sreg1, ins->dreg);
+          else
+            {
+              alpha_sll_(code, ins->sreg1, 24, alpha_at);
+              alpha_addl(code, alpha_at, alpha_zero, ins->dreg);
+              alpha_sra_(code, ins->dreg, 24, ins->dreg);
+            }
           break;
 
         case CEE_CONV_I2:
           // Move I2 (word) to dreg(64 bits) and sign extend it
           CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i2] sreg=%d, dreg=%d\n",
                  ins->sreg1, ins->dreg);
-          alpha_sll_(code, ins->sreg1, 16, alpha_at);
-          alpha_addl(code, alpha_at, alpha_zero, ins->dreg);
-          alpha_sra_(code, ins->dreg, 16, ins->dreg);
+          if (bwx_supported)
+            alpha_sextw(code, ins->sreg1, ins->dreg);
+          else
+            {
+              alpha_sll_(code, ins->sreg1, 16, alpha_at);
+              alpha_addl(code, alpha_at, alpha_zero, ins->dreg);
+              alpha_sra_(code, ins->dreg, 16, ins->dreg);
+            }
           break;
           
         case CEE_CONV_I4:
@@ -3300,6 +3425,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:
@@ -3312,26 +3438,50 @@ 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:
           // Allocate sreg1 bytes on stack, round bytes by 8,
           // modify SP, set dreg to end of current stack frame
           // top of stack is used for call params
-          CFG_DEBUG(4) g_print("ALPHA_FIX: [localloc] sreg=%d, dreg=%d\n",
+          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:
@@ -3443,6 +3593,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);
@@ -3450,6 +3606,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);
@@ -3457,6 +3619,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);
@@ -3464,6 +3632,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);
@@ -3489,7 +3663,7 @@ 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);
           
@@ -3647,7 +3821,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, 
@@ -3655,10 +3829,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,
@@ -3666,12 +3840,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
              alpha_ret(code, alpha_ra, 1);
 
-       }
-       break;
+          }
+          break;
         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,
@@ -3697,7 +3871,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                  MONO_PATCH_INFO_BB,
                                  ins->inst_target_bb);
             alpha_bsr(code, alpha_ra, 0);
-
           }
           break;
           
@@ -3707,8 +3880,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
           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,
@@ -3716,26 +3889,28 @@ 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, mono_profiler_method_leave, code, FALSE);
+              code = mono_arch_instrument_epilog (cfg,
+                                  mono_profiler_method_leave, code, FALSE);
             g_assert (!cfg->method->save_lmf);
 
             alpha_mov1( code, alpha_fp, alpha_sp );
@@ -3762,7 +3937,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__);
@@ -3949,7 +4173,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;
 
@@ -3964,7 +4188,7 @@ 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) ||
@@ -4198,7 +4422,20 @@ mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
 void
 mono_arch_cpu_init (void)
 {
-   ALPHA_DEBUG("mono_arch_cpu_init");
+  unsigned long amask, implver;
+  register long v0 __asm__("$0") = -1;
+  ALPHA_DEBUG("mono_arch_cpu_init");
+
+  __asm__ (".long 0x47e00c20" : "=r"(v0) : "0"(v0));
+  amask = ~v0;
+  __asm__ (".long 0x47e03d80" : "=r"(v0));
+  implver = v0;
+
+  if (amask & 1)
+    bwx_supported = 1;
+
+  //printf("amask: %x, implver: %x", amask, implver);
 }
 
 
@@ -4623,7 +4860,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) {
@@ -4886,9 +5123,9 @@ mono_arch_get_global_int_regs (MonoCompile *cfg)
    
    CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_get_global_int_regs");
    
-   regs = g_list_prepend (regs, (gpointer)alpha_r9);
-   regs = g_list_prepend (regs, (gpointer)alpha_r10);
-   regs = g_list_prepend (regs, (gpointer)alpha_r11);
+//   regs = g_list_prepend (regs, (gpointer)alpha_r9);
+//   regs = g_list_prepend (regs, (gpointer)alpha_r10);
+//   regs = g_list_prepend (regs, (gpointer)alpha_r11);
    regs = g_list_prepend (regs, (gpointer)alpha_r12);
    regs = g_list_prepend (regs, (gpointer)alpha_r13);
    regs = g_list_prepend (regs, (gpointer)alpha_r14);
@@ -4898,42 +5135,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                */
@@ -4961,7 +5162,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
 
    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];
 
@@ -4990,7 +5191,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);
@@ -5151,7 +5352,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)
            {
@@ -5515,8 +5716,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
 
@@ -5546,13 +5745,24 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 
    CFG_DEBUG(3) g_print ("ALPHA: args_save_area_offset at %d(%x)\n", offset, offset);
 
-   // Consider floats passed in regs too
-   for (i = 0; i < (PARAM_REGS*2); ++i)
-     if (i < (sig->param_count + sig->hasthis))
-        //(cfg->used_int_regs & (1 << param_regs[i])))
-       {
-        offset += sizeof (gpointer);
-       }
+   for (i = 0; i < sig->param_count + sig->hasthis; ++i)
+     {
+       ArgInfo *ainfo = &cinfo->args [i];
+
+       switch(ainfo->storage)
+        {
+        case ArgInIReg:
+        case ArgInFloatReg:
+        case ArgInDoubleReg:
+          offset += sizeof (gpointer);
+          break;
+        case ArgAggregate:
+          offset += ainfo->nregs * sizeof (gpointer);
+          break;
+        default:
+          ;
+        }
+     }
 
    CFG_DEBUG(3) g_print ("ALPHA: Stack size is %d(%x)\n",
                          offset, offset);
@@ -5560,7 +5770,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)
         {
@@ -5713,19 +5923,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");
 
@@ -5737,7 +5948,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
       )