* mini-ops.h: Add s390_backchain instruction
authorNeale Ferguson <neale@mono-cvs.ximian.com>
Wed, 21 Dec 2005 21:46:19 +0000 (21:46 -0000)
committerNeale Ferguson <neale@mono-cvs.ximian.com>
Wed, 21 Dec 2005 21:46:19 +0000 (21:46 -0000)
* inssel-s390.brg: Use backchaining instruction for LOADARG/STKARG operations.

* cpu-s390.md: Add s390_backchain instruction

* mini-s390.c: Significant ABI changes

* mini-s390.h: Cater for zero length structures

svn path=/trunk/mono/; revision=54708

mono/mini/ChangeLog
mono/mini/cpu-s390.md
mono/mini/inssel-s390.brg
mono/mini/mini-ops.h
mono/mini/mini-s390.c
mono/mini/mini-s390.h

index 157f1f3416efdc4e9b6e93c0d17fc34fc8b03c7c..896cc03831be80aba8f79318a0442be1899cde10 100644 (file)
@@ -1,3 +1,15 @@
+2005-12-21 Neale Ferguson <neale@sinenomine.net>
+
+       * mini-ops.h: Add s390_backchain instruction
+
+       * inssel-s390.brg: Use backchaining instruction for LOADARG/STKARG operations.
+
+       * cpu-s390.md: Add s390_backchain instruction
+
+       * mini-s390.c: Significant ABI changes
+
+       * mini-s390.h: Cater for zero length structures
+
 2005-12-20 Neale Ferguson <neale@sinenomine.net>
 
        * mini-s390.c: ABI fixes
index 7c94cac7ed0a157a6bc3db5e94ff34f90dacff9b..fe5ada5c97e17e9f4da701ff487aa11313aa9fb8 100644 (file)
@@ -450,6 +450,7 @@ rem_un_imm: dest:i src1:i src2:i len:24
 rename:
 ret:
 retarg:
+s390_bkchain: len:16 dest:i src1:i
 s390_move: len:48 dest:b src1:b
 s390_setf4ret: dest:f src1:f len:4
 tls_get: dest:i len:44
index a39c93a01be6eb059ab75a0da93d21f56b7aa939..1b76266e9b4cef02881aa30d296ebcbaa348736b 100644 (file)
@@ -144,11 +144,11 @@ stmt: OP_SETRET (freg) {
        if (mono_method_signature (s->method)->ret->type == MONO_TYPE_R4) {
                tree->opcode = OP_S390_SETF4RET;
                tree->sreg1  = state->left->reg1;
-               tree->dreg   = s390_f0;
+//             tree->dreg   = s390_f0;
        } else {
                tree->opcode = OP_FMOVE;
                tree->sreg1  = state->left->reg1;
-               tree->dreg   = s390_f0;
+//             tree->dreg   = s390_f0;
        }
        mono_bblock_add_inst (s->cbb, tree);
 }
@@ -325,12 +325,12 @@ stmt: OP_OUTARG_MEMBASE (CEE_LDIND_REF (OP_REGVAR)) {
 #      mono_bblock_add_inst (s->cbb, tree);
 #}
 
-stmt: OP_OUTARG (OP_LDADDR (OP_S390_LOADARG)) {
-       MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, tree->unused,
-                            state->left->left->tree->sreg1,
-                            state->left->left->tree->inst_offset);
-}
-
+#stmt: OP_OUTARG (OP_LDADDR (OP_S390_LOADARG)) {
+#      MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, tree->unused,
+#                           state->left->left->tree->sreg1,
+#                           state->left->left->tree->inst_offset);
+#}
+#
 stmt: OP_OUTARG_MEMBASE (OP_LDADDR (OP_S390_LOADARG)) {
        MonoCallArgParm *arg = (MonoCallArgParm *) tree; 
 
@@ -348,10 +348,15 @@ stmt: OP_OUTARG_MEMBASE (OP_LDADDR (OP_S390_LOADARG)) {
 #                           state->left->left->tree->inst_offset);
 #}
 
+freg: OP_FCONV_TO_R4 (freg) "0" {
+       /* The conversion is done elsewhere */
+       MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
+}
+
 stmt: OP_OUTARG_R4 (freg) {
        MonoCallInst *call = (MonoCallInst*)tree->inst_right;
 
-       tree->opcode = OP_FCONV_TO_R4;
+       tree->opcode = OP_S390_SETF4RET;
        tree->dreg   = mono_regstate_next_float (s->rs);
        tree->sreg1  = state->left->reg1;
        mono_bblock_add_inst (s->cbb, tree);
@@ -496,32 +501,14 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGPTR)) {
        int start_reg = tree->sreg1;
        int size      = arg->size;
        int soffset   = vt->inst_offset;
-       int treg;
 
-       if (size < 0) { 
-               size = -size;
-               treg = mono_regstate_next_int (s->rs);
-               if (start_reg != STK_BASE) {
-                       MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offset,
-                                           vt->inst_basereg, soffset, size);
-                       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
-                                                STK_BASE, arg->offPrm);
-                       mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
-               } else {
-                       MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm,
-                                           vt->inst_basereg, soffset, size);
-                       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
-                       MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
-                                                    STK_BASE, arg->offset, treg);
-               }
+       if (start_reg != STK_BASE) {
+               MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
        } else {
-               if (start_reg != STK_BASE) {
-                       MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
-               } else {
-                       MONO_OUTPUT_VTS (s, size, STK_BASE, arg->offset,
-                                        vt->inst_basereg, soffset);
-               }       
-       }
+               
+               MONO_OUTPUT_VTS (s, size, STK_BASE, arg->offset,
+                                vt->inst_basereg, soffset);
+       }       
 }
 
 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_REGOFFSET)) "0" {
@@ -568,23 +555,43 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_LOADARG)) {
        MonoCallArgParm *arg = (MonoCallArgParm *) tree; 
        MonoInst *vt         = state->left->left->tree;
        
-       int start_reg = tree->sreg1;
+       int start_reg = tree->inst_basereg;
        int size      = -arg->size;
        int soffset   = vt->inst_offset;
        int treg;
 
 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_LOADARG))\n");
        treg = mono_regstate_next_int (s->rs);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
+       MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, vt->unused);
+       MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset, treg, 0, size);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, soffset);
        if (start_reg != STK_BASE) {
-               MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, soffset);
-               MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm, treg, 0, size);
-               MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
-                                        STK_BASE, arg->offPrm);
                mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
        } else {
-               MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm,
-                                   vt->inst_basereg, soffset, size);
-               MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
+               MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
+                                            STK_BASE, arg->offset, treg);
+       }
+}
+
+stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGREG)) {
+       MonoCallInst *call   = (MonoCallInst*) tree->inst_right;
+       MonoCallArgParm *arg = (MonoCallArgParm *) tree; 
+       MonoInst *vt         = state->left->left->tree;
+       
+       int base_reg = tree->inst_basereg;
+       int size     = -arg->size;
+       int soffset  = vt->inst_offset;
+       int treg;
+
+//printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_ARGREG))\n");
+       treg = mono_regstate_next_int (s->rs);
+       MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, s->frame_reg, soffset);
+       MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm, treg, 0, size);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
+       if (base_reg != STK_BASE) {
+               mono_call_inst_add_outarg_reg (call, treg, base_reg, FALSE);
+       } else {
                MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
                                             STK_BASE, arg->offset, treg);
        }
@@ -632,7 +639,6 @@ stmt: OP_OUTARG_VT (reg) {
                                                 STK_BASE, arg->offPrm);
                        mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
                } else {
-//printf("OP_OUTARG_VT(reg) 1\n");
                        MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset+size, state->left->reg1,
                                            0, size);
                        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
@@ -641,7 +647,6 @@ stmt: OP_OUTARG_VT (reg) {
                                                     STK_BASE, arg->offset, treg);
                }
        } else {
-//printf("OP_OUTARG_VT(reg) 2\n");
                if (start_reg != STK_BASE) {
                        MONO_OUTPUT_VTR (s, size, start_reg, STK_BASE, soffset);
                } else {
@@ -763,8 +768,7 @@ base: OP_S390_STKARG "0" {
        int treg;
 
        treg = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, STK_BASE, 0);
-//     MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, s->frame_reg, 0);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
        tree->inst_offset  = state->tree->inst_offset;
        tree->inst_basereg = treg;
 }
@@ -778,8 +782,8 @@ base: OP_LDADDR (OP_S390_LOADARG) "0" {
        int treg;
 
        treg = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg, 
-                                state->left->tree->inst_offset);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
+       MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, state->left->tree->unused);
        tree->inst_offset  = 0;
        tree->inst_basereg = treg;
 }
@@ -797,19 +801,21 @@ base: OP_LDADDR (OP_S390_ARGPTR) "0" {
 base: OP_LDADDR (OP_S390_STKARG) "0" {
        int treg;
 
+printf("base: OP_LDADDR(OP_S390_STKARG) 0\n");
        treg = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, STK_BASE, 0);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, treg, 
                                 state->left->tree->inst_offset);
        tree->inst_offset  = 0;
        tree->inst_basereg = treg;
 }
 
-reg: OP_LDADDR (OP_S390_LOADARG) "2" {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
-                                state->left->tree->inst_offset);
-       tree->inst_offset  = 0;
-       tree->inst_basereg = state->reg1;
+reg: OP_LDADDR (OP_S390_LOADARG) {
+       int treg;
+
+       treg = mono_regstate_next_int (s->rs);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
+       MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, treg, state->left->tree->inst_offset);
 }
 
 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
@@ -820,10 +826,10 @@ reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
 }
 
 reg: OP_LDADDR (OP_S390_STKARG) "2" {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
-                                (s->stack_offset + state->left->tree->unused));
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 
-                                state->left->tree->inst_offset);
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, state->reg1, s->frame_reg);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
+                                (state->left->tree->unused +
+                                 state->left->tree->inst_offset));
        tree->inst_offset  = 0;
        tree->inst_basereg = state->reg1;
 }
@@ -839,10 +845,11 @@ reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
 }
 
 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
-                                (s->stack_offset + state->left->tree->unused));
+printf("reg: CEE_LDOBJ(OP_S390_STKARG)\n");
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, state->reg1, s->frame_reg);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
-                                state->left->tree->inst_offset);
+                                (state->left->tree->inst_offset + 
+                                 state->left->tree->unused));
        tree->inst_offset  = 0;
        tree->inst_basereg = state->reg1;
 }
@@ -861,8 +868,8 @@ base: CEE_LDOBJ (OP_S390_STKARG) "0" {
        int treg;
 
        treg = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
-                                (s->stack_offset + state->left->tree->unused));
+       MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, treg, state->left->tree->unused);
        MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, state->left->tree->inst_offset);
        tree->inst_offset  = 0;
        tree->inst_basereg = treg;
index 645ef2544758c12a61c9f282c939dbe9f28b8017..f6e64936c3ae4e88356f6c3be517e7344fe8a19a 100644 (file)
@@ -602,6 +602,7 @@ MINI_OP(OP_S390_ARGPTR,        "s390_argptr")
 MINI_OP(OP_S390_STKARG,           "s390_stkarg")
 MINI_OP(OP_S390_MOVE,             "s390_move")
 MINI_OP(OP_S390_SETF4RET,         "s390_setf4ret")
+MINI_OP(OP_S390_BKCHAIN,          "s390_bkchain")
 
 MINI_OP(OP_IA64_LOAD,          "ia64_load")
 MINI_OP(OP_IA64_LOADI1,        "ia64_loadi1")
index c99388796f802cbee350146155cf5f46d8df2933..9e8ff698ba1611e93a1a2543804eb4515bfa301d 100644 (file)
@@ -718,8 +718,6 @@ fseek(stdout, 0L, SEEK_SET);
 lc = 0;
 }
        fname = mono_method_full_name (method, TRUE);
-if (strcmp(fname,"NUnit.Framework.Assertion:AssertEquals (string,object,object)") == 0)
-printf("!!\n");
        indent (1);
        printf ("ENTER: %s(", fname);
        g_free (fname);
@@ -735,7 +733,7 @@ printf("!!\n");
        cinfo = calculate_sizes (sig, &sz, sig->pinvoke);
 
        if (cinfo->struct_ret) {
-               printf ("[VALUERET:%p], ", (gpointer) rParm->gr[0]);
+               printf ("[STRUCTRET:%p], ", (gpointer) rParm->gr[0]);
                iParm = 1;
        }
 
@@ -983,21 +981,39 @@ handle_enum:
                        }
 
                        size = mono_type_size (type, &align);
-                       printf ("[");
-                       for (j = 0; p && j < size; j++)
-                               printf ("%02x,", p [j]);
-                       printf ("]");
-               }
+                       switch (size) {
+                       case 1:
+                       case 2:
+                       case 4:
+                       case 8:
+                               printf ("[");
+                               for (j = 0; p && j < size; j++)
+                                       printf ("%02x,", p [j]);
+                               printf ("]\n");
+                               break;
+                       default:
+                               printf ("[VALUERET]\n");
+                       }
+               }       
                break;
        }
        case MONO_TYPE_TYPEDBYREF: {
                guint8 *p = va_arg (ap, gpointer);
                int j, size, align;
                size = mono_type_size (type, &align);
-               printf ("[");
-               for (j = 0; p && j < size; j++)
-                       printf ("%02x,", p [j]);
-               printf ("]");
+               switch (size) {
+               case 1:
+               case 2:
+               case 4:
+               case 8:
+                       printf ("[");
+                       for (j = 0; p && j < size; j++)
+                               printf ("%02x,", p [j]);
+                       printf ("]\n");
+                       break;
+               default:
+                       printf ("[TYPEDBYREF]\n");
+               }
        }
                break;
        default:
@@ -1235,7 +1251,6 @@ add_stackParm (guint *gr, size_data *sz, ArgInfo *ainfo, gint size)
 {
        if (*gr > S390_LAST_ARG_REG) {
                sz->stack_size  = S390_ALIGN(sz->stack_size, sizeof(long));
-               ainfo->offset   = sz->stack_size;
                ainfo->reg      = STK_BASE;
                sz->parm_size  += sizeof(gpointer);
                sz->offStruct  += sizeof(gpointer);
@@ -1243,13 +1258,13 @@ add_stackParm (guint *gr, size_data *sz, ArgInfo *ainfo, gint size)
                ainfo->reg      = *gr;
        }
        (*gr) ++;
+       ainfo->offset   = sz->stack_size;
        ainfo->offparm  = sz->offset;
        sz->offset      = S390_ALIGN(sz->offset+size, sizeof(long));
        ainfo->size     = size;
        ainfo->regtype  = RegTypeStructByAddr; 
        ainfo->vtsize   = size;
        sz->parm_size  += size;
-
 }
 
 /*========================= End of Function ========================*/
@@ -1586,7 +1601,9 @@ enum_retvalue:
                }
        }
 
-       sz->stack_size  = S390_ALIGN(sz->stack_size+sz->offset, sizeof(long));
+       sz->stack_size  = sz->stack_size + sz->local_size + sz->parm_size + 
+                         sz->offset;
+       sz->stack_size  = S390_ALIGN(sz->stack_size, sizeof(long));
 
        return (cinfo);
 }
@@ -1706,12 +1723,14 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                        size               = abs(cinfo->args[iParm].vtsize);
                                        offset             = S390_ALIGN(offset, sizeof(long));
                                        inst->inst_offset  = offset; 
+                                       inst->unused       = 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;
                                }
                                        break;
                                case RegTypeStructByVal :
@@ -1720,6 +1739,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;
                                        break;
                                default :
                                if (cinfo->args[iParm].reg != STK_BASE) {
@@ -1780,8 +1800,9 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        /*------------------------------------------------------*/
        /* Allow space for the trace method stack area if needed*/
        /*------------------------------------------------------*/
-       if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method)) 
+       if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method)) {
                offset += S390_TRACE_STACK_SIZE;
+       }
 
        /*------------------------------------------------------*/
        /* Reserve space to save LMF and caller saved registers */
@@ -1819,6 +1840,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
        CallInfo *cinfo;
        ArgInfo *ainfo;
        size_data sz;
+       int stackSize;
 
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
@@ -1826,8 +1848,8 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb,
        
        cinfo = calculate_sizes (sig, &sz, sig->pinvoke);
 
-       call->stack_usage = MAX((sz.stack_size + sz.local_size + sz.parm_size), 
-                               call->stack_usage);
+       stackSize         = sz.stack_size + sz.local_size + sz.parm_size + sz.offset;
+       call->stack_usage = MAX(stackSize, call->stack_usage);
        lParamArea        = MAX((call->stack_usage-S390_MINIMAL_STACK_SIZE-sz.parm_size), 0);
        cfg->param_area   = MAX(((signed) cfg->param_area), lParamArea);
        cfg->flags       |= MONO_CFG_HAS_CALLS;
@@ -3290,6 +3312,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_FCONV_TO_R4: {
+                       NOT_IMPLEMENTED("OP_FCONV_TO_R4");
                        if ((ins->next) &&
                             (ins->next->opcode != OP_FMOVE) &&
                             (ins->next->opcode != OP_STORER4_MEMBASE_REG))
@@ -3913,6 +3936,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_lr  (code, ins->dreg, s390_r0);
                }
                        break;  
+               case OP_S390_BKCHAIN: {
+                       s390_lr  (code, ins->dreg, ins->sreg1);
+                       if (s390_is_imm16 (cfg->stack_offset)) {
+                               s390_ahi (code, ins->dreg, cfg->stack_offset);
+                       } else {
+                               s390_basr (code, s390_r13, 0);
+                               s390_j    (code, 6);
+                               s390_word (code, cfg->stack_offset);
+                               s390_a    (code, ins->dreg, 0, s390_r13, 4);
+                       }
+               }
+                       break;  
                default:
                        g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
                        g_assert_not_reached ();
@@ -4316,7 +4351,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                                break;
                                }
                        } else if (ainfo->regtype == RegTypeStructByAddr) {
-                               s390_st  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+                               if (ainfo->reg != STK_BASE) 
+                                       s390_st  (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
                        } else
                                g_assert_not_reached ();
                }
@@ -4839,6 +4875,12 @@ mono_arch_print_tree (MonoInst *tree, int arity)
                                tree->inst_imm,
                                mono_arch_regname (tree->sreg1));
                        done = 1;
+                       break;
+               case OP_S390_BKCHAIN:
+                       printf ("[previous_frame(%s)]", 
+                               mono_arch_regname (tree->sreg1));
+                       done = 1;
+                       break;
                default:
                        done = 0;
        }
index f1200357266335ae55b7386b3f9e052375b13822..e17d56dbbccfb3289381de269f7834a69615fa47 100644 (file)
 #define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do {                            \
        int reg = mono_regstate_next_int (cfg->rs);                             \
        switch (size) {                                                         \
+               case 0:                                                         \
+                       MONO_EMIT_NEW_ICONST(cfg, reg, 0);                      \
+                       mono_call_inst_add_outarg_reg (call, reg, dr, FALSE);   \
+               break;                                                          \
                case 1:                                                         \
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE,   \
                                reg, sr, so);                                   \
 #define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do {                                \
        int tmpr;                                                               \
        switch (size) {                                                         \
+               case 0:                                                         \
+                       tmpr = mono_regstate_next_int (cfg->rs);                \
+                       MONO_EMIT_NEW_ICONST(cfg, tmpr, 0);                     \
+                       MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG,  \
+                               dr, dx, tmpr);                                  \
+               break;                                                          \
                case 1:                                                         \
                        tmpr = mono_regstate_next_int (cfg->rs);                \
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE,   \