/* P r o t o t y p e s */
/*------------------------------------------------------------------*/
-static guint32 * emit_memcpy (guint8 *, int, int, int, int, int);
+static guint8 * emit_memcpy (guint8 *, int, int, int, int, int);
static void indent (int);
-static guint8 * backUpStackPtr(MonoCompile *, guint8 *);
+static guint8 * backUpStackPtr(MonoCompile *, guint8 *, gint);
static void decodeParm (MonoType *, void *, int);
static void enter_method (MonoMethod *, RegParm *, char *);
static void leave_method (MonoMethod *, ...);
static CallInfo * calculate_sizes (MonoMethodSignature *, size_data *, gboolean);
static void peephole_pass (MonoCompile *, MonoBasicBlock *);
static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
-static unsigned char * mono_emit_stack_alloc (guchar *, MonoInst *);
static void mono_arch_break(void);
gpointer mono_arch_get_lmf_addr (void);
+static guint8 * emit_load_volatile_registers(guint8 *, MonoCompile *);
/*========================= End of Prototypes ======================*/
/* */
/*------------------------------------------------------------------*/
-static guint32*
+static guint8 *
emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffset)
{
switch (size) {
/*------------------------------------------------------------------*/
static inline guint8 *
-backUpStackPtr(MonoCompile *cfg, guint8 *code)
+backUpStackPtr(MonoCompile *cfg, guint8 *code, gint framePtr)
{
int stackSize = cfg->stack_usage;
if (s390_is_uimm16 (cfg->stack_usage)) {
- s390_ahi (code, STK_BASE, cfg->stack_usage);
+ s390_ahi (code, framePtr, cfg->stack_usage);
} else {
while (stackSize > 32767) {
- s390_ahi (code, STK_BASE, 32767);
+ s390_ahi (code, framePtr, 32767);
stackSize -= 32767;
}
- s390_ahi (code, STK_BASE, stackSize);
+ s390_ahi (code, framePtr, stackSize);
}
return (code);
}
printf ("[UINTPTR:%p], ", *((int **) curParm));
break;
case MONO_TYPE_BOOLEAN :
- printf ("[BOOL:%p], ", *((int *) curParm));
+ printf ("[BOOL:%d], ", *((int *) curParm));
break;
case MONO_TYPE_CHAR :
- printf ("[CHAR:%p], ", *((int *) curParm));
+ printf ("[CHAR:%c], ", *((int *) curParm));
break;
case MONO_TYPE_I1 :
printf ("[INT1:%d], ", *((int *) curParm));
g_free (fname);
ip = (*(guint32 *) (sp+S390_RET_ADDR_OFFSET)) & 0x7fffffff;
- printf (") ip: %p sp: %p - ", ip, sp);
+ printf (") ip: %p sp: %p - ", (gpointer) ip, sp);
if (rParm == NULL)
return;
cinfo = calculate_sizes (sig, &sz, sig->pinvoke);
if (cinfo->struct_ret) {
- printf ("[VALUERET:%p], ", rParm->gr[0]);
+ printf ("[VALUERET:%p], ", (gpointer) rParm->gr[0]);
iParm = 1;
}
break;
}
case MONO_TYPE_I: {
- int *val = va_arg (ap, int*);
+ int val = va_arg (ap, int);
printf ("[INT:%d]", val);
printf("]");
break;
}
case MONO_TYPE_U: {
- int *val = va_arg (ap, int*);
+ int val = va_arg (ap, int);
printf ("[UINT:%d]", val);
printf("]");
break;
}
ip = ((gint32) __builtin_return_address (0)) & 0x7fffffff;
- printf (" ip: %p\n", ip);
+ printf (" ip: %p\n", (gpointer) ip);
}
/*========================= End of Function ========================*/
inst->opcode = OP_REGOFFSET;
inst->inst_basereg = frame_reg;
offset += size;
- DEBUG (g_print("allocating local %d to %d\n", iVar, inst->inst_offset));
+ DEBUG (g_print("allocating local %d to %ld\n", iVar, inst->inst_offset));
}
/*------------------------------------------------------*/
/* Allow space for the trace method stack area if needed*/
/*------------------------------------------------------*/
- if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg))
+ if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method))
offset += S390_TRACE_STACK_SIZE;
/*------------------------------------------------------*/
/*========================= End of Function ========================*/
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_emit_stack_alloc */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-static unsigned char*
-mono_emit_stack_alloc (guchar *code, MonoInst* tree)
-{
- return code;
-}
-
-/*========================= End of Function ========================*/
-
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_output_basic_block */
s390_alcr (code, ins->dreg, src2);
}
break;
- case OP_ADDCC_IMM:
case OP_ADD_IMM: {
+ if ((ins->next) &&
+ (ins->next->opcode == OP_ADC_IMM)) {
+ s390_basr (code, s390_r13, 0);
+ s390_j (code, 4);
+ s390_word (code, ins->inst_imm);
+ if (ins->dreg != ins->sreg1) {
+ s390_lr (code, ins->dreg, ins->sreg1);
+ }
+ s390_a (code, ins->dreg, 0, s390_r13, 4);
+ } else {
+ if (s390_is_imm16 (ins->inst_imm)) {
+ if (ins->dreg != ins->sreg1) {
+ s390_lr (code, ins->dreg, ins->sreg1);
+ }
+ s390_ahi (code, ins->dreg, ins->inst_imm);
+ } else {
+ s390_basr (code, s390_r13, 0);
+ s390_j (code, 4);
+ s390_word (code, ins->inst_imm);
+ if (ins->dreg != ins->sreg1) {
+ s390_lr (code, ins->dreg, ins->sreg1);
+ }
+ s390_a (code, ins->dreg, 0, s390_r13, 4);
+ }
+ }
+ }
+ break;
+ case OP_ADDCC_IMM: {
if ((ins->next) &&
(ins->next->opcode == OP_ADC_IMM)) {
s390_basr (code, s390_r13, 0);
if (ins->dreg != ins->sreg1) {
s390_lr (code, ins->dreg, ins->sreg1);
}
- s390_ahi (code, ins->dreg, ins->inst_imm);
+ s390_lhi (code, s390_r0, ins->inst_imm);
+ s390_alcr (code, ins->dreg, s390_r0);
} else {
s390_basr (code, s390_r13, 0);
s390_j (code, 4);
if (ins->dreg != ins->sreg1) {
s390_lr (code, ins->dreg, ins->sreg1);
}
- s390_a (code, ins->dreg, 0, s390_r13, 4);
+ s390_al (code, ins->dreg, 0, s390_r13, 4);
}
}
}
if (ins->dreg != ins->sreg1) {
s390_lr (code, ins->dreg, ins->sreg1);
}
- s390_ahi (code, ins->dreg, -ins->inst_imm);
+ s390_lhi (code, s390_r0, ins->inst_imm);
+ s390_slr (code, ins->dreg, s390_r0);
} else {
s390_basr (code, s390_r13, 0);
s390_j (code, 4);
}
break;
case CEE_JMP: {
- int iParm, fParm, pOffset;
if (cfg->method->save_lmf)
restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
if (cfg->flags & MONO_CFG_HAS_TAIL) {
- pOffset = S390_PARM_SAVE_OFFSET;
- s390_l (code, s390_r13, 0, STK_BASE, 0);
- for (iParm = s390_r2;
- iParm <= s390_r5;
- iParm++, pOffset+sizeof(gint32)) {
- if (cfg->used_int_regs & (1 << iParm))
- s390_l (code, iParm, 0, s390_r13, pOffset);
- }
- pOffset = S390_FLOAT_SAVE_OFFSET;
- for (fParm = 0;
- fParm < 4;
- fParm++, pOffset+sizeof(double))
- s390_ld (code, fParm, 0, s390_r13, pOffset);
+ code = emit_load_volatile_registers(code, cfg);
}
- code = backUpStackPtr(cfg, code);
+ code = backUpStackPtr(cfg, code, STK_BASE);
s390_l (code, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
mono_add_patch_info (cfg, code - cfg->native_code,
MONO_PATCH_INFO_METHOD_JUMP,
g_assert_not_reached ();
break;
case OP_LOCALLOC: {
-// int alloca_skip = S390_MINIMAL_STACK_SIZE + cfg->param_area +
-// S390_STACK_ALIGNMENT - 1;
-// int area_offset = S390_ALIGN(alloca_skip, S390_STACK_ALIGNMENT);
int area_offset = S390_MINIMAL_STACK_SIZE;
s390_lr (code, s390_r1, ins->sreg1);
if (ins->flags & MONO_INST_INIT)
target = S390_RELATIVE(target, ip);
ip += 2;
}
- s390_patch (ip, target);
+ s390_patch (ip, (guint32) target);
+ }
+}
+
+/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - emit_load_volatile_registers */
+/* */
+/* Function - Create the instruction sequence for loading the */
+/* parameter registers for use with the 'tail' op. */
+/* */
+/* The register loading operations performed here */
+/* are the mirror of the store operations performed */
+/* in mono_arch_emit_prolog and need to be kept in */
+/* synchronization with it. */
+/* */
+/*------------------------------------------------------------------*/
+
+guint8 *
+emit_load_volatile_registers(guint8 * code, MonoCompile *cfg)
+{
+ MonoMethod *method = cfg->method;
+ MonoMethodSignature *sig;
+ MonoInst *inst;
+ int pos, i;
+ CallInfo *cinfo;
+ size_data sz;
+
+ sig = mono_method_signature (method);
+ pos = 0;
+
+ cinfo = calculate_sizes (sig, &sz, sig->pinvoke);
+
+ if (cinfo->struct_ret) {
+ ArgInfo *ainfo = &cinfo->ret;
+ inst = cfg->ret;
+ s390_l (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];
+
+ if (inst->opcode == OP_REGVAR) {
+ if (ainfo->regtype == RegTypeGeneral)
+ s390_lr (code, ainfo->reg, inst->dreg);
+ else if (ainfo->regtype == RegTypeFP) {
+ if (inst->dreg != ainfo->reg) {
+ if (ainfo->size == 4) {
+ s390_ldebr (code, ainfo->reg, inst->dreg);
+ } else {
+ s390_ldr (code, ainfo->reg, inst->dreg);
+ }
+ }
+ }
+ else if (ainfo->regtype == RegTypeBase) {
+ } else
+ g_assert_not_reached ();
+ } else {
+ if (ainfo->regtype == RegTypeGeneral) {
+ if (!((ainfo->reg >= 2) && (ainfo->reg <= 6)))
+ g_assert_not_reached();
+ switch (ainfo->size) {
+ case 1:
+ s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ break;
+ case 2:
+ s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ break;
+ case 8:
+ s390_lm (code, ainfo->reg, ainfo->reg + 1,
+ inst->inst_basereg, inst->inst_offset);
+ break;
+ default:
+ s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ }
+ } else if (ainfo->regtype == RegTypeBase) {
+ } else if (ainfo->regtype == RegTypeFP) {
+ if (ainfo->size == 8)
+ s390_ld (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ else if (ainfo->size == 4)
+ s390_le (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ else
+ g_assert_not_reached ();
+ } else if (ainfo->regtype == RegTypeStructByVal) {
+ if (ainfo->reg != STK_BASE) {
+ switch (ainfo->size) {
+ case 1:
+ s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ break;
+ case 2:
+ s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ break;
+ case 4:
+ s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ break;
+ case 8:
+ s390_lm (code, ainfo->reg, ainfo->reg+1, inst->inst_basereg, inst->inst_offset);
+ break;
+ }
+ }
+ } else if (ainfo->regtype == RegTypeStructByAddr) {
+ if (ainfo->reg != STK_BASE) {
+ s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ }
+ } else
+ g_assert_not_reached ();
+ }
+ pos++;
}
+
+ g_free (cinfo);
+
+ return code;
}
/*========================= End of Function ========================*/
cfg->code_size = 512;
cfg->native_code = code = g_malloc (cfg->code_size);
- if (cfg->flags & MONO_CFG_HAS_TAIL) {
- s390_stm (code, s390_r2, s390_r14, STK_BASE, S390_PARM_SAVE_OFFSET);
- for (pos = 0; pos < 4; pos++)
- s390_std (code, pos, 0, STK_BASE,
- S390_FLOAT_SAVE_OFFSET+pos*sizeof(double));
- } else {
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- }
+ s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
if (cfg->flags & MONO_CFG_HAS_ALLOCA) {
cfg->used_int_regs |= 1 << 11;
inst->inst_offset, s390_r13, 0);
} else {
s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
-// code = emit_memcpy (code, abs(ainfo->vtsize),
-// inst->inst_basereg,
-// inst->inst_offset,
-// ainfo->reg, 0);
}
} else
g_assert_not_reached ();
void
mono_arch_emit_epilog (MonoCompile *cfg)
{
- MonoJumpInfo *patch_info;
MonoMethod *method = cfg->method;
int tracing = 0;
guint8 *code;
restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
if (cfg->flags & MONO_CFG_HAS_ALLOCA)
- s390_l (code, STK_BASE, 0, STK_BASE, 0);
+ s390_l (code, STK_BASE, 0, STK_BASE, 0);
else
- code = backUpStackPtr(cfg, code);
+ code = backUpStackPtr(cfg, code, STK_BASE);
s390_lm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
s390_br (code, s390_r14);
/*-----------------------------------------------------*/
/* Patch the branch in epilog to come here */
/*-----------------------------------------------------*/
- s390_patch (ip + 2, S390_RELATIVE(code,ip));
+ s390_patch (ip + 2, (guint32) (S390_RELATIVE(code,ip)));
exc_class = mono_class_from_name (mono_defaults.corlib,
"System",
break;
if (iExc < nThrows) {
- s390_jcl (code, S390_CC_UN, exc_throw_start [iExc]);
+ s390_jcl (code, S390_CC_UN, (guint32) exc_throw_start [iExc]);
patch_info->type = MONO_PATCH_INFO_NONE;
} else {
case OP_S390_LOADARG:
case OP_S390_ARGREG:
case OP_S390_ARGPTR:
- printf ("[0x%x(%s)]", tree->inst_offset,
+ printf ("[0x%lx(%s)]", tree->inst_offset,
mono_arch_regname (tree->inst_basereg));
done = 1;
break;
case OP_S390_STKARG:
- printf ("[0x%x(previous_frame)]",
+ printf ("[0x%lx(previous_frame)]",
tree->inst_offset);
done = 1;
break;
case OP_S390_MOVE:
- printf ("[0x%x(%d,%s),0x%x(%s)]",
+ printf ("[0x%lx(%d,%s),0x%lx(%s)]",
tree->inst_offset, tree->unused,
- tree->dreg, tree->inst_imm,
- tree->sreg1);
+ mono_arch_regname(tree->dreg), tree->inst_imm,
+ mono_arch_regname(tree->sreg1));
done = 1;
break;
case OP_S390_SETF4RET:
- printf ("[f%d,f%d]",
+ printf ("[f%ld,f%ld]",
mono_arch_regname (tree->dreg),
mono_arch_regname (tree->sreg1));
done = 1;
break;
case OP_TLS_GET:
- printf ("[0x%x(0x%x,%s)]", tree->inst_offset,
+ printf ("[0x%lx(0x%lx,%s)]", tree->inst_offset,
tree->inst_imm,
mono_arch_regname (tree->sreg1));
done = 1;