Test case for bug#325444.
[mono.git] / mono / mini / mini-s390x.c
index becb840bc5c599560fcca605a81a842af56b14f8..86f1fd5f9843311dd99f1c15c5f529e91181847c 100644 (file)
@@ -202,25 +202,6 @@ typedef struct {
              retStruct;
 } size_data;   
 
-typedef enum {
-       CMP_EQ,
-       CMP_NE,
-       CMP_LE,
-       CMP_GE,
-       CMP_LT,
-       CMP_GT,
-       CMP_LE_UN,
-       CMP_GE_UN,
-       CMP_LT_UN,
-       CMP_GT_UN
-} CompRelation;
-
-typedef enum {
-       CMP_TYPE_L,
-       CMP_TYPE_I,
-       CMP_TYPE_F
-} CompType;
-
 /*------------------------------------------------------------------*/
 /* Used by the instrument_emit_epilog                              */
 /*------------------------------------------------------------------*/
@@ -262,6 +243,7 @@ typedef struct {
 
 typedef struct {
        int nargs;
+       int lastgr;
        guint32 stack_usage;
        guint32 struct_ret;
        ArgInfo ret;
@@ -297,6 +279,7 @@ gpointer mono_arch_get_lmf_addr (void);
 static guint8 * emit_load_volatile_registers (guint8 *, MonoCompile *);
 static CompRelation opcode_to_cond (int);
 static void catch_SIGILL(int, siginfo_t *, void *);
+static void emit_sig_cookie (MonoCompile *, MonoCallInst *, CallInfo *, int);
 
 /*========================= End of Prototypes ======================*/
 
@@ -310,8 +293,6 @@ static int indent_level = 0;
 
 int has_ld = 0;
 
-static const char*const * ins_spec = s390x_cpu_desc;
-
 static gboolean tls_offset_inited = FALSE;
 
 static int appdomain_tls_offset = -1,
@@ -556,7 +537,7 @@ enum_parmtype:
                                printf ("[BOOL:%ld], ", *((gint64 *) curParm));
                                break;
                        case MONO_TYPE_CHAR :
-                               printf ("[CHAR:%c], ", *((gint64  *) curParm));
+                               printf ("[CHAR:%c], ", *((int  *) curParm));
                                break;
                        case MONO_TYPE_I1 :
                                printf ("[INT1:%ld], ", *((gint64 *) curParm));
@@ -599,7 +580,7 @@ enum_parmtype:
                                        printf("%p [%p] ",obj,curParm);
                                        if (class == mono_defaults.string_class) {
                                                printf("[STRING:%p:%s]", 
-                                                      obj, mono_string_to_utf8 (obj));
+                                                      obj, mono_string_to_utf8 ((MonoString *) obj));
                                        } else if (class == mono_defaults.int32_class) { 
                                                printf("[INT32:%p:%d]", 
                                                        obj, *(gint32 *)((char *)obj + sizeof (MonoObject)));
@@ -1077,6 +1058,23 @@ mono_arch_cpu_init (void)
 
 /*========================= End of Function ========================*/
 
+
+/*
+ * Initialize architecture specific code.
+ */
+void
+mono_arch_init (void)
+{
+}
+
+/*
+ * Cleanup architecture specific code.
+ */
+void
+mono_arch_cleanup (void)
+{
+}
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_cpu_optimizazions                       */
@@ -1119,6 +1117,8 @@ is_regsize_var (MonoType *t) {
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
        case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_FNPTR:
                return TRUE;
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_STRING:
@@ -1392,8 +1392,8 @@ enum_retvalue:
                        /* Fall through */
                case MONO_TYPE_VALUETYPE: {
                        MonoClass *klass = mono_class_from_mono_type (sig->ret);
-                       if (sig->ret->data.klass->enumtype) {
-                               simpletype = sig->ret->data.klass->enum_basetype->type;
+                       if (klass->enumtype) {
+                               simpletype = klass->enum_basetype->type;
                                goto enum_retvalue;
                        }
                        if (sig->pinvoke)
@@ -1598,6 +1598,15 @@ enum_retvalue:
                }
        }
 
+       /*----------------------------------------------------------*/
+       /* Handle the case where there are no implicit arguments    */
+       /*----------------------------------------------------------*/
+       if ((sig->call_convention == MONO_CALL_VARARG) &&
+           (sig->param_count == sig->sentinelpos)) {
+               gr = S390_LAST_ARG_REG + 1;
+               add_general (&gr, sz, &cinfo->sigCookie);
+       }
+
        /*----------------------------------------------------------*/
        /* If we are passing a structure back then if it won't be   */
        /* in a register(s) then we make room at the end of the     */
@@ -1617,6 +1626,7 @@ enum_retvalue:
                }
        }
 
+       cinfo->lastgr   = gr;
        sz->stack_size  = sz->stack_size + sz->local_size + sz->parm_size + 
                          sz->offset;
        sz->stack_size  = S390_ALIGN(sz->stack_size, sizeof(long));
@@ -1712,7 +1722,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        }
 
        if (sig->hasthis) {
-               inst = cfg->varinfo [0];
+               inst = cfg->args [0];
                if (inst->opcode != OP_REGVAR) {
                        inst->opcode       = OP_REGOFFSET;
                        inst->inst_basereg = frame_reg;
@@ -1731,7 +1741,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                cfg->sig_cookie += S390_MINIMAL_STACK_SIZE;
 
        for (iParm = sArg; iParm < eArg; ++iParm) {
-               inst = cfg->varinfo [curinst];
+               inst = cfg->args [curinst];
                if (inst->opcode != OP_REGVAR) {
                        switch (cinfo->args[iParm].regtype) {
                                case RegTypeStructByAddr :
@@ -1741,14 +1751,14 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                        offset             = S390_ALIGN(offset, sizeof(long));
                                        inst->inst_offset  = offset; 
                                        size               = abs(cinfo->args[iParm].vtsize);
-                                       inst->unused       = cinfo->args[iParm].offset;
+                                       inst->backend.arg_info     = cinfo->args[iParm].offset;
                                } else {
                                        inst->opcode       = OP_S390_ARGREG;
                                        inst->inst_basereg = frame_reg;
                                        size               = sizeof(gpointer);
                                        offset             = S390_ALIGN(offset, size);
                                        inst->inst_offset  = offset;
-                                       inst->unused       = cinfo->args[iParm].offset;
+                                       inst->backend.arg_info     = cinfo->args[iParm].offset;
                                }
                                        break;
                                case RegTypeStructByVal :
@@ -1757,7 +1767,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                        size               = cinfo->args[iParm].size;
                                        offset             = S390_ALIGN(offset, size);
                                        inst->inst_offset  = offset;
-                                       inst->unused       = cinfo->args[iParm].offset;
+                                       inst->backend.arg_info     = cinfo->args[iParm].offset;
                                        break;
                                default :
                                if (cinfo->args[iParm].reg != STK_BASE) {
@@ -1776,7 +1786,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                                              : 0);
                                        inst->inst_offset  = cinfo->args[iParm].offset + 
                                                             size;
-                                       inst->unused       = 0;
+                                       inst->backend.arg_info       = 0;
                                        size               = sizeof(long);
                                } 
                        }
@@ -1798,11 +1808,11 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                        continue;
 
                /*--------------------------------------------------*/
-               /* inst->unused indicates native sized value types, */
+               /* inst->backend.is_pinvoke indicates native sized value types, */
                /* this is used by the pinvoke wrappers when they   */
                /* call functions returning structure               */
                /*--------------------------------------------------*/
-               if (inst->unused && MONO_TYPE_ISSTRUCT (inst->inst_vtype))
+               if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype))
                        size = mono_class_native_size (mono_class_from_mono_type(inst->inst_vtype), &align);
                else
                        size = mono_type_size (inst->inst_vtype, &align);
@@ -1876,22 +1886,10 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
        for (i = 0; i < n; ++i) {
                ainfo = cinfo->args + i;
 
-               if ((sig->call_convention == MONO_CALL_VARARG) &&
+               if (!(sig->pinvoke) &&
+                   (sig->call_convention == MONO_CALL_VARARG) &&
                    (i == sig->sentinelpos)) {
-                       MonoInst *sigArg;
-                       
-                       cfg->disable_aot = TRUE;
-                       MONO_INST_NEW (cfg, sigArg, OP_ICONST);
-                       sigArg->inst_p0 = call->signature;
-
-                       MONO_INST_NEW_CALL_ARG (cfg, arg, OP_OUTARG_MEMBASE);
-                       arg->ins.inst_left   = sigArg;
-                       arg->ins.inst_right  = (MonoInst *) call;
-                       arg->size            = ainfo->size;
-                       arg->offset          = cinfo->sigCookie.offset;
-                       call->used_iregs    |= 1 << ainfo->reg;
-                       arg->ins.next        = call->out_args;
-                       call->out_args       = (MonoInst *) arg;
+                       emit_sig_cookie (cfg, call, cinfo, ainfo->size);
                }
 
                if (is_virtual && i == 0) {
@@ -1904,12 +1902,13 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                        arg->ins.cil_code   = in->cil_code;
                        arg->ins.inst_left  = in;
                        arg->ins.type       = in->type;
+
                        /* prepend, we'll need to reverse them later */
                        arg->ins.next       = call->out_args;
                        call->out_args      = (MonoInst *) arg;
                        arg->ins.inst_right = (MonoInst *) call;
                        if (ainfo->regtype == RegTypeGeneral) {
-                               arg->ins.unused = ainfo->reg;
+                               arg->ins.backend.reg3 = ainfo->reg;
                                call->used_iregs |= 1 << ainfo->reg;
                        } else if (ainfo->regtype == RegTypeStructByAddr) {
                                call->used_iregs |= 1 << ainfo->reg;
@@ -1933,7 +1932,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                                arg->offset       = ainfo->offset;
                                call->used_iregs |= 1 << ainfo->reg;
                        } else if (ainfo->regtype == RegTypeFP) {
-                               arg->ins.unused = ainfo->reg;
+                               arg->ins.backend.reg3 = ainfo->reg;
                                call->used_fregs |= 1 << ainfo->reg;
                                if (ainfo->size == 4)
                                        arg->ins.opcode = OP_OUTARG_R4;
@@ -1944,6 +1943,16 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
                        }
                }
        }
+
+       /*
+        * Handle the case where there are no implicit arguments 
+        */
+       if (!(sig->pinvoke) &&
+           (sig->call_convention == MONO_CALL_VARARG) &&
+           (n == sig->sentinelpos)) {
+               emit_sig_cookie (cfg, call, cinfo, sizeof(MonoType *));
+       }
+
        /*
         * Reverse the call->out_args list.
         */
@@ -1964,6 +1973,55 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - emit_sig_cookie.                                  */
+/*                                                                  */
+/* Function    - For variable length parameter lists construct a   */
+/*               signature cookie and emit it.                     */
+/*                                                                 */
+/*------------------------------------------------------------------*/
+
+static void
+emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, 
+                CallInfo *cinfo, int argSize)
+{
+       MonoCallArgParm *arg;
+       MonoMethodSignature *tmpSig;
+       MonoInst *sigArg;
+                       
+       cfg->disable_aot = TRUE;
+
+       /*----------------------------------------------------------*/
+       /* mono_ArgIterator_Setup assumes the signature cookie is   */
+       /* passed first and all the arguments which were before it  */
+       /* passed on the stack after the signature. So compensate   */
+       /* by passing a different signature.                        */
+       /*----------------------------------------------------------*/
+       tmpSig = mono_metadata_signature_dup (call->signature);
+       tmpSig->param_count -= call->signature->sentinelpos;
+       tmpSig->sentinelpos  = 0;
+       if (tmpSig->param_count > 0)
+               memcpy (tmpSig->params, 
+                       call->signature->params + call->signature->sentinelpos, 
+                       tmpSig->param_count * sizeof(MonoType *));
+
+       MONO_INST_NEW (cfg, sigArg, OP_ICONST);
+       sigArg->inst_p0 = tmpSig;
+
+       MONO_INST_NEW_CALL_ARG (cfg, arg, OP_OUTARG_MEMBASE);
+       arg->ins.inst_left   = sigArg;
+       arg->ins.inst_right  = (MonoInst *) call;
+       arg->size            = argSize;
+       arg->offset          = cinfo->sigCookie.offset;
+
+       /* prepend, we'll need to reverse them later */
+       arg->ins.next       = call->out_args;
+       call->out_args      = (MonoInst *) arg;
+}
+
+/*========================= End of Function ========================*/
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_instrument_mem_needs                    */
@@ -2249,14 +2307,8 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (last_ins && (last_ins->opcode == OP_STOREI1_MEMBASE_REG) &&
                                        ins->inst_basereg == last_ins->inst_destbasereg &&
                                        ins->inst_offset == last_ins->inst_offset) {
-                               if (ins->dreg == last_ins->sreg1) {
-                                       last_ins->next = ins->next;                             
-                                       ins = ins->next;                                
-                                       continue;
-                               } else {
-                                       ins->opcode = OP_MOVE;
-                                       ins->sreg1 = last_ins->sreg1;
-                               }
+                               ins->opcode = (ins->opcode == OP_LOADI1_MEMBASE) ? CEE_CONV_I1 : CEE_CONV_U1;
+                               ins->sreg1 = last_ins->sreg1;                           
                        }
                        break;
                case OP_LOADU2_MEMBASE:
@@ -2264,14 +2316,8 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (last_ins && (last_ins->opcode == OP_STOREI2_MEMBASE_REG) &&
                                        ins->inst_basereg == last_ins->inst_destbasereg &&
                                        ins->inst_offset == last_ins->inst_offset) {
-                               if (ins->dreg == last_ins->sreg1) {
-                                       last_ins->next = ins->next;                             
-                                       ins = ins->next;                                
-                                       continue;
-                               } else {
-                                       ins->opcode = OP_MOVE;
-                                       ins->sreg1 = last_ins->sreg1;
-                               }
+                               ins->opcode = (ins->opcode == OP_LOADI2_MEMBASE) ? CEE_CONV_I2 : CEE_CONV_U2;
+                               ins->sreg1 = last_ins->sreg1;                           
                        }
                        break;
                case CEE_CONV_I4:
@@ -2431,7 +2477,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        while (ins) {
                offset = code - 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)) {
                        cfg->code_size *= 2;
@@ -2544,7 +2590,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LOADI1_MEMBASE: {
-                       S390_LONG (code, lb, lb, ins->dreg, 0, 
+                       S390_LONG (code, lgb, lgb, ins->dreg, 0, 
                                   ins->inst_basereg, ins->inst_offset);
                }
                        break;
@@ -2660,7 +2706,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;
-               case CEE_BREAK: {
+               case OP_BREAK: {
                        s390_basr  (code, s390_r13, 0);
                        s390_j     (code, 6);
                        mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, 
@@ -2699,34 +2745,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                }
                        break;
-//             case OP_ADDCC_IMM: {
-//                     if ((ins->next) &&
-//                         (ins->next->opcode == OP_ADC_IMM)) {
-//                             s390_basr (code, s390_r13, 0);
-//                             s390_j    (code, 6);
-//                             s390_llong(code, ins->inst_imm);
-//                             if (ins->dreg != ins->sreg1) {
-//                                     s390_lgr  (code, ins->dreg, ins->sreg1);
-//                             }
-//                             s390_alg  (code, ins->dreg, 0, s390_r13, 4);
-//                     } else {
-//                             if (s390_is_imm16 (ins->inst_imm)) {
-//                                     if (ins->dreg != ins->sreg1) {
-//                                             s390_lgr  (code, ins->dreg, ins->sreg1);
-//                                     }
-//                                     s390_aghi (code, ins->dreg, ins->inst_imm);
-//                             } else {
-//                                     s390_basr (code, s390_r13, 0);
-//                                     s390_j    (code, 6);
-//                                     s390_llong(code, ins->inst_imm);
-//                                     if (ins->dreg != ins->sreg1) {
-//                                             s390_lgr  (code, ins->dreg, ins->sreg1);
-//                                     }
-//                                     s390_ag   (code, ins->dreg, 0, s390_r13, 4);
-//                             }
-//                     }
-//             }
-//                     break;
                case OP_ADC_IMM: {
                        if (ins->dreg != ins->sreg1) {
                                s390_lgr  (code, ins->dreg, ins->sreg1);
@@ -3508,7 +3526,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                s390_ledbr (code, ins->dreg, ins->sreg1);
                }
                        break;
-               case CEE_JMP: {
+               case OP_JMP: {
                        if (cfg->method->save_lmf)
                                restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
 
@@ -3669,7 +3687,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_THROW: {
+               case OP_THROW: {
                        s390_lgr  (code, s390_r2, ins->sreg1);
                        s390_basr (code, s390_r13, 0);
                        s390_j    (code, 6);
@@ -3706,7 +3724,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                }
                        break;
-               case CEE_ENDFINALLY: {
+               case OP_ENDFINALLY: {
                        S390_LONG (code, lg, lg, s390_r14, 0, 
                                   ins->inst_left->inst_basereg, 
                                   ins->inst_left->inst_offset);
@@ -3723,7 +3741,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ins->inst_c0 = code - cfg->native_code;
                }
                        break;
-               case CEE_BR: 
+               case OP_BR: 
                        EMIT_UNCOND_BRANCH(ins);
                        break;
                case OP_BR_REG: {
@@ -4031,37 +4049,57 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lghi  (code, ins->dreg, 0);
                }
                        break;
-               case OP_FBEQ:
-                       EMIT_COND_BRANCH (ins, S390_CC_EQ|S390_CC_OV);
+               case OP_FBEQ: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
+                       EMIT_COND_BRANCH (ins, S390_CC_EQ);
+                       PTRSLOT (code, o);
+               }
                        break;
                case OP_FBNE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_NE|S390_CC_OV);
                        break;
-               case OP_FBLT:
+               case OP_FBLT: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_LT);
+                       PTRSLOT (code, o);
+               }
                        break;
                case OP_FBLT_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_LT|S390_CC_OV);
                        break;
-               case OP_FBGT:
+               case OP_FBGT: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_GT);
+                       PTRSLOT (code, o);
+               }
                        break;
                case OP_FBGT_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_GT|S390_CC_OV);
                        break;
-               case OP_FBGE:
+               case OP_FBGE: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_GE);
+                       PTRSLOT (code, o);
+               }
                        break;
                case OP_FBGE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_GE|S390_CC_OV);
                        break;
-               case OP_FBLE:
+               case OP_FBLE: {
+                       short *o;
+                       s390_jo (code, 0); CODEPTR(code, o);
                        EMIT_COND_BRANCH (ins, S390_CC_LE);
+                       PTRSLOT (code, o);
+               }
                        break;
                case OP_FBLE_UN:
                        EMIT_COND_BRANCH (ins, S390_CC_LE|S390_CC_OV);
                        break;
-               case CEE_CKFINITE: {
+               case OP_CKFINITE: {
                        short *o;
                        s390_lhi  (code, s390_r13, 0x7f);
                        s390_tcdb (code, ins->sreg1, 0, s390_r13, 0);
@@ -4073,9 +4111,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_S390_MOVE: {
-                       if (ins->unused > 0) {
-                               if (ins->unused <= 256) {
-                                       s390_mvc  (code, ins->unused, ins->dreg, 
+                       if (ins->backend.size > 0) {
+                               if (ins->backend.size <= 256) {
+                                       s390_mvc  (code, ins->backend.size, ins->dreg, 
                                                   ins->inst_offset, ins->sreg1, ins->inst_imm);
                                } else {
                                        s390_lgr  (code, s390_r0, ins->dreg);
@@ -4107,18 +4145,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_ATOMIC_ADD_I8: {
                        s390_lgr (code, s390_r1, ins->sreg2);
                        s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_ag  (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_csg (code, s390_r0, s390_r0, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -11);
+                       s390_agr (code, s390_r1, s390_r0);
+                       s390_csg (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
+                       s390_jnz (code, -10);
                        s390_lgr (code, ins->dreg, s390_r1);
                }
                        break;  
                case OP_ATOMIC_ADD_NEW_I8: {
                        s390_lgr (code, s390_r1, ins->sreg2);
                        s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_ag  (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
+                       s390_agr (code, s390_r1, s390_r0);
                        s390_csg (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -11);
+                       s390_jnz (code, -10);
                        s390_lgr (code, ins->dreg, s390_r1);
                }
                        break;  
@@ -4130,28 +4168,28 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;  
                case OP_ATOMIC_ADD_I4: {
-                       s390_lr  (code, s390_r1, ins->sreg2);
-                       s390_l   (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_a   (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_cs  (code, s390_r0, s390_r0, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -7);
-                       s390_lr  (code, ins->dreg, s390_r1);
+                       s390_lgfr(code, s390_r1, ins->sreg2);
+                       s390_lgf (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
+                       s390_agr (code, s390_r1, s390_r0);
+                       s390_cs  (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
+                       s390_jnz (code, -9);
+                       s390_lgfr(code, ins->dreg, s390_r1);
                }
                        break;  
                case OP_ATOMIC_ADD_NEW_I4: {
-                       s390_lr  (code, s390_r1, ins->sreg2);
-                       s390_l   (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
-                       s390_a   (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
+                       s390_lgfr(code, s390_r1, ins->sreg2);
+                       s390_lgf (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
+                       s390_agr (code, s390_r1, s390_r0);
                        s390_cs  (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
-                       s390_jnz (code, -7);
-                       s390_lr  (code, ins->dreg, s390_r1);
+                       s390_jnz (code, -9);
+                       s390_lgfr(code, ins->dreg, s390_r1);
                }
                        break;  
                case OP_ATOMIC_EXCHANGE_I4: {
-                       s390_l   (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
+                       s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
                        s390_cs  (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
                        s390_jnz (code, -4);
-                       s390_lr  (code, ins->dreg, s390_r0);
+                       s390_lgfr(code, ins->dreg, s390_r0);
                }
                        break;  
                case OP_S390_BKCHAIN: {
@@ -4325,7 +4363,7 @@ emit_load_volatile_registers (guint8 *code, MonoCompile *cfg)
 
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = cinfo->args + i;
-               inst = cfg->varinfo [pos];
+               inst = cfg->args [pos];
 
                if (inst->opcode == OP_REGVAR) {
                        if (ainfo->regtype == RegTypeGeneral)
@@ -4348,7 +4386,7 @@ emit_load_volatile_registers (guint8 *code, MonoCompile *cfg)
                                        g_assert_not_reached();
                                switch (ainfo->size) {
                                case 1:
-                                       s390_icy  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+                                       s390_llgc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
                                        break;
                                case 2:
                                        s390_lgh  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
@@ -4372,7 +4410,7 @@ emit_load_volatile_registers (guint8 *code, MonoCompile *cfg)
                                if (ainfo->reg != STK_BASE) {
                                        switch (ainfo->size) {
                                        case 1:
-                                               s390_icy (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+                                               s390_llgc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
                                                break;
                                        case 2:
                                                s390_lgh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
@@ -4475,7 +4513,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        max_offset += 6; 
 
                while (ins) {
-                       max_offset += ((guint8 *)ins_spec [ins->opcode])[MONO_INST_LEN];
+                       max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
                        ins = ins->next;
                }
        }
@@ -4489,13 +4527,13 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        if (cinfo->struct_ret) {
                ArgInfo *ainfo = &cinfo->ret;
                inst         = cfg->ret;
-               inst->unused = ainfo->vtsize;
+               inst->backend.size = ainfo->vtsize;
                s390_stg (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
        }
 
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = cinfo->args + i;
-               inst = cfg->varinfo [pos];
+               inst = cfg->args [pos];
 
                if (inst->opcode == OP_REGVAR) {
                        if (ainfo->regtype == RegTypeGeneral)
@@ -4756,8 +4794,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                        iExc;
        guint32         code_size;
        MonoClass       *exc_classes [MAX_EXC];
-       guint8          *exc_throw_start [MAX_EXC], 
-                       *exc_throw_end [MAX_EXC];
+       guint8          *exc_throw_start [MAX_EXC];
 
        for (patch_info = cfg->patch_info; 
             patch_info; 
@@ -5089,7 +5126,7 @@ mono_arch_print_tree (MonoInst *tree, int arity)
                        break;
                case OP_S390_MOVE:
                        printf ("[0x%lx(%d,%s),0x%lx(%s)]",
-                               tree->inst_offset, tree->unused,
+                               tree->inst_offset, tree->backend.size,
                                mono_arch_regname(tree->dreg), 
                                tree->inst_imm, 
                                mono_arch_regname(tree->sreg1));
@@ -5332,3 +5369,21 @@ opcode_to_cond (int opcode)
 }
 
 /*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_get_patch_offset                        */
+/*                                                                  */
+/* Function    - Dummy entry point until s390x supports aot.       */
+/*                                                                 */
+/* Returns     - Offset for patch.                                 */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
+guint32
+mono_arch_get_patch_offset (guint8 *code)
+{
+       return 0;
+}
+
+/*========================= End of Function ========================*/