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);
}
# 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;
# 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);
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" {
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);
}
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,
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 {
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;
}
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;
}
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" {
}
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;
}
}
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;
}
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;
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);
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;
}
}
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:
{
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);
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 ========================*/
}
}
- 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);
}
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 :
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) {
/*------------------------------------------------------*/
/* 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 */
CallInfo *cinfo;
ArgInfo *ainfo;
size_data sz;
+ int stackSize;
sig = call->signature;
n = sig->param_count + sig->hasthis;
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;
}
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))
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 ();
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 ();
}
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;
}