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 */
/*------------------------------------------------------------------*/
typedef struct {
int nargs;
+ int lastgr;
guint32 stack_usage;
guint32 struct_ret;
ArgInfo ret;
/* P r o t o t y p e s */
/*------------------------------------------------------------------*/
-static guint8 * emit_memcpy (guint8 *, int, int, int, int, int);
static void indent (int);
static guint8 * backUpStackPtr(MonoCompile *, guint8 *);
static void decodeParm (MonoType *, void *, int);
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 ======================*/
static int indent_level = 0;
-static const char*const * ins_spec = s390x_cpu_desc;
+int has_ld = 0;
static gboolean tls_offset_inited = FALSE;
/*========================= End of Function ========================*/
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_memcpy */
-/* */
-/* Function - Emit code to move from memory-to-memory based on */
-/* the size of the variable. r0 is overwritten. */
-/* */
-/*------------------------------------------------------------------*/
-
-static guint8 *
-emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffset)
-{
- switch (size) {
- case 4 :
- s390_ly (code, s390_r0, 0, sreg, soffset);
- s390_sty (code, s390_r0, 0, dreg, doffset);
- break;
-
- case 3 :
- s390_icmy (code, s390_r0, 14, sreg, soffset);
- s390_stcmy (code, s390_r0, 14, dreg, doffset);
- break;
-
- case 2 :
- s390_lhy (code, s390_r0, 0, sreg, soffset);
- s390_sthy (code, s390_r0, 0, dreg, doffset);
- break;
-
- case 1 :
- s390_icy (code, s390_r0, 0, sreg, soffset);
- s390_stcy (code, s390_r0, 0, dreg, doffset);
- break;
-
- default :
- while (size > 0) {
- int len;
-
- if (size > 256)
- len = 256;
- else
- len = size;
- s390_mvc (code, len, dreg, doffset, sreg, soffset);
- size -= len;
- }
- }
- return code;
-}
-
-/*========================= End of Function ========================*/
-
/*------------------------------------------------------------------*/
/* */
/* Name - arch_get_argument_info */
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));
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)));
/*========================= End of Function ========================*/
-static int lc = 0;
/*------------------------------------------------------------------*/
/* */
/* Name - enter_method */
size_data sz;
void *curParm;
-
-lc++;
-if (lc > 500000) {
-fseek(stdout, 0L, SEEK_SET);
-lc = 0;
-}
fname = mono_method_full_name (method, TRUE);
indent (1);
printf ("ENTER: %s ", fname);
printf ("this:[NULL], ");
} else {
if (obj) {
-// class = obj->vtable->klass;
-// if (class == mono_defaults.string_class) {
-// printf ("this:[STRING:%p:%s], ",
-// obj, mono_string_to_utf8 ((MonoString *)obj));
-// } else {
-// printf ("this:%p[%s.%s], ",
-// obj, class->name_space, class->name);
-// }
-printf("this:%p, ",obj);
+ class = obj->vtable->klass;
+ if (class == mono_defaults.string_class) {
+ printf ("this:[STRING:%p:%s], ",
+ obj, mono_string_to_utf8 ((MonoString *)obj));
+ } else {
+ printf ("this:%p[%s.%s], ",
+ obj, class->name_space, class->name);
+ }
} else
printf ("this:NULL, ");
}
decodeParm(sig->params[i], sp+ainfo->offset, ainfo->size);
break;
case RegTypeStructByVal :
- if (ainfo->reg != STK_BASE)
- curParm = &(rParm->gr[ainfo->reg-2]);
+ if (ainfo->reg != STK_BASE) {
+ int offset = sizeof(glong) - ainfo->size;
+ curParm = &(rParm->gr[ainfo->reg-2])+offset;
+ }
else
curParm = sp+ainfo->offset;
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - catch_SIGILL */
+/* */
+/* Function - Catch SIGILL as a result of testing for long */
+/* displacement facility. */
+/* */
+/*------------------------------------------------------------------*/
+
+void
+catch_SIGILL(int sigNo, siginfo_t *info, void *act) {
+
+ has_ld = 0;
+
+}
+
+/*========================= End of Function ========================*/
+
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_cpu_init */
void
mono_arch_cpu_init (void)
{
+ struct sigaction sa,
+ *oldSa = NULL;
guint mode = 1;
/*--------------------------------------*/
/*--------------------------------------*/
__asm__ ("SRNM\t%0\n\t"
: : "m" (mode));
+
+ /*--------------------------------------*/
+ /* Determine if we have long displace- */
+ /* ment facility on this processor */
+ /*--------------------------------------*/
+ sa.sa_sigaction = catch_SIGILL;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+
+ sigaction (SIGILL, &sa, oldSa);
+
+ /*--------------------------------------*/
+ /* We test by executing the STY inst */
+ /*--------------------------------------*/
+ __asm__ ("LGHI\t0,1\n\t"
+ "LA\t1,%0\n\t"
+ ".byte\t0xe3,0x00,0x10,0x00,0x00,0x50\n\t"
+ : "=m" (has_ld) : : "0", "1");
+
+ sigaction (SIGILL, oldSa, NULL);
}
/*========================= 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 */
guint32 opts = 0;
/*----------------------------------------------------------*/
- /* no s390-specific optimizations yet */
+ /* No s390-specific optimizations yet */
/*----------------------------------------------------------*/
*exclude_mask = MONO_OPT_INLINE|MONO_OPT_LINEARS;
// *exclude_mask = MONO_OPT_INLINE;
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:
cinfo->ret.reg = s390_r2;
sz->code_size += 4;
break;
+ case MONO_TYPE_GENERICINST:
+ if (!mono_type_generic_inst_is_valuetype (sig->ret)) {
+ cinfo->ret.reg = s390_r2;
+ sz->code_size += 4;
+ break;
+ }
+ /* 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)
add_float (&fr, sz, cinfo->args+nParm);
nParm++;
break;
+ case MONO_TYPE_GENERICINST:
+ if (!mono_type_generic_inst_is_valuetype (sig->params [i])) {
+ cinfo->args[nParm].size = sizeof(gpointer);
+ add_general (&gr, sz, cinfo->args+nParm);
+ nParm++;
+ break;
+ }
+ /* Fall through */
case MONO_TYPE_VALUETYPE: {
MonoMarshalType *info;
MonoClass *klass = mono_class_from_mono_type (sig->params [i]);
}
}
+ /*----------------------------------------------------------*/
+ /* 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 */
}
}
+ 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));
}
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;
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 :
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 :
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) {
: 0);
inst->inst_offset = cinfo->args[iParm].offset +
size;
- inst->unused = 0;
+ inst->backend.arg_info = 0;
size = sizeof(long);
}
}
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);
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) {
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;
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;
}
}
}
+
+ /*
+ * 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.
*/
/*========================= 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 */
{
guchar *code = p;
int parmOffset,
- fpOffset;
+ fpOffset,
+ baseReg;
parmOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
if (cfg->method->save_lmf)
parmOffset -= sizeof(MonoLMF);
fpOffset = parmOffset + (5*sizeof(gpointer));
+ if ((!has_ld) && (fpOffset > 4096)) {
+ s390_lgr (code, s390_r12, STK_BASE);
+ baseReg = s390_r12;
+ while (fpOffset > 4096) {
+ s390_aghi (code, baseReg, 4096);
+ fpOffset -= 4096;
+ parmOffset -= 4096;
+ }
+ } else {
+ baseReg = STK_BASE;
+ }
s390_stmg (code, s390_r2, s390_r6, STK_BASE, parmOffset);
- s390_stdy (code, s390_f0, 0, STK_BASE, fpOffset);
- s390_stdy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
- s390_stdy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
- s390_stdy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
+ if (has_ld) {
+ s390_stdy (code, s390_f0, 0, STK_BASE, fpOffset);
+ s390_stdy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
+ s390_stdy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
+ s390_stdy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
+ } else {
+ s390_std (code, s390_f0, 0, baseReg, fpOffset);
+ s390_std (code, s390_f2, 0, baseReg, fpOffset+sizeof(gdouble));
+ s390_std (code, s390_f4, 0, baseReg, fpOffset+2*sizeof(gdouble));
+ s390_std (code, s390_f6, 0, baseReg, fpOffset+3*sizeof(gdouble));
+ }
s390_basr (code, s390_r13, 0);
s390_j (code, 10);
s390_llong(code, cfg->method);
s390_llong(code, func);
s390_lg (code, s390_r2, 0, s390_r13, 4);
- s390_lay (code, s390_r3, 0, STK_BASE, parmOffset);
+ if (has_ld)
+ s390_lay (code, s390_r3, 0, STK_BASE, parmOffset);
+ else
+ s390_la (code, s390_r3, 0, baseReg, parmOffset);
s390_lgr (code, s390_r4, STK_BASE);
s390_aghi (code, s390_r4, cfg->stack_usage);
s390_lg (code, s390_r1, 0, s390_r13, 12);
s390_basr (code, s390_r14, s390_r1);
- s390_ldy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
- s390_ldy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
- s390_ldy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
- s390_ldy (code, s390_f0, 0, STK_BASE, fpOffset);
+ if (has_ld) {
+ s390_ldy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
+ s390_ldy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
+ s390_ldy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
+ s390_ldy (code, s390_f0, 0, STK_BASE, fpOffset);
+ } else {
+ s390_ld (code, s390_f6, 0, baseReg, fpOffset+3*sizeof(gdouble));
+ s390_ld (code, s390_f4, 0, baseReg, fpOffset+2*sizeof(gdouble));
+ s390_ld (code, s390_f2, 0, baseReg, fpOffset+sizeof(gdouble));
+ s390_ld (code, s390_f0, 0, baseReg, fpOffset);
+ }
s390_lmg (code, s390_r2, s390_r6, STK_BASE, parmOffset);
return code;
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:
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:
s390_llong (code, 0x41e0000000000000);
s390_llong (code, 0x41f0000000000000);
s390_ldr (code, s390_f15, sreg);
- s390_cdb (code, s390_f15, 0, s390_r13, 0);
+ s390_cdb (code, s390_f15, 0, s390_r13, 4);
s390_jl (code, 0); CODEPTR (code, o[0]);
- s390_sdb (code, s390_f15, 0, s390_r13, 8);
+ s390_sdb (code, s390_f15, 0, s390_r13, 12);
s390_cfdbr (code, dreg, 7, s390_f15);
s390_j (code, 4);
PTRSLOT (code, o[0]);
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;
switch (ins->opcode) {
case OP_STOREI1_MEMBASE_IMM: {
s390_lghi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm20(ins->inst_offset))
- s390_stcy(code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, stcy, stc, s390_r0, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STOREI2_MEMBASE_IMM: {
s390_lghi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_sthy (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, sthy, sth, s390_r0, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STOREI4_MEMBASE_IMM: {
s390_llong(code, ins->inst_imm);
s390_lg (code, s390_r0, 0, s390_r13, 4);
}
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_sty (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, sty, st, s390_r0, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STORE_MEMBASE_IMM:
s390_llong(code, ins->inst_imm);
s390_lg (code, s390_r0, 0, s390_r13, 4);
}
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_stg (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_stg (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, stg, stg, s390_r0, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STOREI1_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_stcy (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, stcy, stc, ins->sreg1, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STOREI2_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_sthy (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, sthy, sth, ins->sreg1, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STOREI4_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_sty (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, sty, st, ins->sreg1, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STORE_MEMBASE_REG:
case OP_STOREI8_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_stg (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_stg (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, stg, stg, ins->sreg1, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case CEE_LDIND_I:
break;
case OP_LOAD_MEMBASE:
case OP_LOADI8_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_lg (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lg (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, lg, lg, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADI4_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_lgf (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lgf (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, lgf, lgf, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADU4_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_llgf (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_llgf (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, llgf, llgf, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADU1_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_llgc (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_llgc (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, llgc, llgc, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADI1_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_lgb (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lgb (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, lgb, lgb, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADU2_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_llgh (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_llgh (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, llgh, llgh, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_LOADI2_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset))
- s390_lgh (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lgh (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, lgh, lgh, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case CEE_CONV_I1: {
}
}
break;
- case OP_X86_TEST_NULL: {
- s390_ltgr (code, ins->sreg1, ins->sreg1);
- }
- 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,
}
}
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);
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);
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);
}
break;
case OP_START_HANDLER: {
- if (s390_is_uimm20 (ins->inst_left->inst_offset)) {
- s390_stg (code, s390_r14, 0,
- ins->inst_left->inst_basereg,
- ins->inst_left->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_left->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_stg (code, s390_r14, s390_r13,
- ins->inst_left->inst_basereg, 0);
- }
+ S390_LONG (code, stg, stg, s390_r14, 0,
+ ins->inst_left->inst_basereg,
+ ins->inst_left->inst_offset);
}
break;
case OP_ENDFILTER: {
if (ins->sreg1 != s390_r2)
s390_lgr(code, s390_r2, ins->sreg1);
- if (s390_is_uimm20 (ins->inst_left->inst_offset)) {
- s390_lg (code, s390_r14, 0, ins->inst_left->inst_basereg,
- ins->inst_left->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_left->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lg (code, s390_r14, s390_r13,
- ins->inst_left->inst_basereg, 0);
- }
+ S390_LONG (code, lg, lg, s390_r14, 0,
+ ins->inst_left->inst_basereg,
+ ins->inst_left->inst_offset);
s390_br (code, s390_r14);
}
break;
- case CEE_ENDFINALLY: {
- if (s390_is_uimm20 (ins->inst_left->inst_offset)) {
- s390_lg (code, s390_r14, 0, ins->inst_left->inst_basereg,
- ins->inst_left->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_left->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_lg (code, s390_r14, s390_r13,
- ins->inst_left->inst_basereg, 0);
- }
+ case OP_ENDFINALLY: {
+ S390_LONG (code, lg, lg, s390_r14, 0,
+ ins->inst_left->inst_basereg,
+ ins->inst_left->inst_offset);
s390_br (code, s390_r14);
}
break;
ins->inst_c0 = code - cfg->native_code;
}
break;
- case CEE_BR:
+ case OP_BR:
EMIT_UNCOND_BRANCH(ins);
break;
case OP_BR_REG: {
}
break;
case OP_STORER8_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_stdy (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_std (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
+ S390_LONG (code, stdy, std, ins->sreg1, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_LOADR8_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_ldy (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_ld (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, ldy, ld, ins->dreg, 0,
+ ins->inst_basereg, ins->inst_offset);
}
break;
case OP_STORER4_MEMBASE_REG: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_stey (code, s390_f15, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_ste (code, s390_f15, s390_r13, ins->inst_destbasereg, 0);
- }
+ s390_ledbr (code, s390_f15, ins->sreg1);
+ S390_LONG (code, stey, ste, s390_f15, 0,
+ ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_LOADR4_MEMBASE: {
- if (s390_is_uimm20(ins->inst_offset)) {
- s390_ldy (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- s390_ldebr (code, ins->dreg, ins->dreg);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_ldeb (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
+ S390_LONG (code, ldy, ld, s390_f15, 0,
+ ins->inst_basereg, ins->inst_offset);
+ s390_ldebr (code, ins->dreg, s390_f15);
}
break;
case CEE_CONV_R_UN: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
+ s390_cdgbr (code, ins->dreg, ins->sreg1);
s390_ltgr (code, ins->sreg1, ins->sreg1);
s390_jnl (code, 12);
s390_basr (code, s390_r13, 0);
PTRSLOT(code, o[4]);
}
break;
+ case OP_ABS: {
+ s390_lpdbr (code, ins->dreg, ins->sreg1);
+ }
+ break;
case OP_SQRT: {
s390_sqdbr (code, ins->dreg, ins->sreg1);
}
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);
}
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);
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_agr (code, s390_r1, s390_r0);
s390_csg (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -7);
+ 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, -7);
+ s390_jnz (code, -10);
s390_lgr (code, ins->dreg, s390_r1);
}
break;
case OP_ATOMIC_EXCHANGE_I8: {
s390_lg (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
s390_csg (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -4);
+ s390_jnz (code, -6);
s390_lgr (code, ins->dreg, s390_r0);
}
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_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_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: {
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)
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);
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);
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;
}
}
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)
g_assert_not_reached();
switch (ainfo->size) {
case 1:
- s390_stcy (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ s390_stc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
break;
case 2:
- s390_sthy (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ s390_sth (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
break;
case 4:
- s390_sty (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
+ s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
break;
case 8:
s390_stg (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
switch (ainfo->size) {
case 1:
if (ainfo->reg == STK_BASE)
- s390_icy (code, reg, 0, s390_r13, ainfo->offset+7);
- s390_stcy (code, reg, 0, inst->inst_basereg, doffset);
+ s390_ic (code, reg, 0, s390_r13, ainfo->offset+7);
+ s390_stc (code, reg, 0, inst->inst_basereg, doffset);
break;
case 2:
if (ainfo->reg == STK_BASE)
- s390_lhy (code, reg, 0, s390_r13, ainfo->offset+6);
- s390_sthy (code, reg, 0, inst->inst_basereg, doffset);
+ s390_lh (code, reg, 0, s390_r13, ainfo->offset+6);
+ s390_sth (code, reg, 0, inst->inst_basereg, doffset);
break;
case 4:
if (ainfo->reg == STK_BASE)
- s390_ly (code, reg, 0, s390_r13, ainfo->offset+4);
- s390_sty (code, reg, 0, inst->inst_basereg, doffset);
+ s390_l (code, reg, 0, s390_r13, ainfo->offset+4);
+ s390_st (code, reg, 0, inst->inst_basereg, doffset);
break;
case 8:
if (ainfo->reg == STK_BASE)
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;
this->sreg1 = this_reg;
this->dreg = mono_regstate_next_int (cfg->rs);
mono_bblock_add_inst (cfg->cbb, this);
- mono_call_inst_add_outarg_reg (inst, this->dreg, this_dreg, FALSE);
+ mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, this_dreg, FALSE);
}
if (vt_reg != -1) {
vtarg->sreg1 = vt_reg;
vtarg->dreg = mono_regstate_next_int (cfg->rs);
mono_bblock_add_inst (cfg->cbb, vtarg);
- mono_call_inst_add_outarg_reg (inst, vtarg->dreg, s390_r2, FALSE);
+ mono_call_inst_add_outarg_reg (cfg, inst, vtarg->dreg, s390_r2, FALSE);
}
}
MONO_INST_NEW (cfg, ins, OP_SQRT);
ins->inst_i0 = args [0];
}
+// if (strcmp (cmethod->name, "Abs") == 0) {
+// MONO_INST_NEW (cfg, ins, OP_ABS);
+// ins->inst_i0 = args [0];
+// }
} else if (cmethod->klass == mono_defaults.thread_class &&
strcmp (cmethod->name, "MemoryBarrier") == 0) {
MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER);
(strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
(strcmp (cmethod->klass->name, "Interlocked") == 0)) {
- if (strcmp (cmethod->name, "Increment") == 0 &&
- fsig->params [0]->type == MONO_TYPE_I4) {
+ if (strcmp (cmethod->name, "Increment") == 0) {
MonoInst *ins_iconst;
+ guint32 opcode = 0;
- MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_NEW_I4);
+ if (fsig->params [0]->type == MONO_TYPE_I4)
+ opcode = OP_ATOMIC_ADD_NEW_I4;
+ else if (fsig->params [0]->type == MONO_TYPE_I8)
+ opcode = OP_ATOMIC_ADD_NEW_I8;
+ else
+ g_assert_not_reached ();
+
+ MONO_INST_NEW (cfg, ins, opcode);
MONO_INST_NEW (cfg, ins_iconst, OP_ICONST);
ins_iconst->inst_c0 = 1;
ins->inst_i0 = args [0];
ins->inst_i1 = ins_iconst;
- } else if (strcmp (cmethod->name, "Decrement") == 0 &&
- fsig->params [0]->type == MONO_TYPE_I4) {
+ } else if (strcmp (cmethod->name, "Decrement") == 0) {
MonoInst *ins_iconst;
+ guint32 opcode = 0;
- MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_NEW_I4);
+ if (fsig->params [0]->type == MONO_TYPE_I4)
+ opcode = OP_ATOMIC_ADD_NEW_I4;
+ else if (fsig->params [0]->type == MONO_TYPE_I8)
+ opcode = OP_ATOMIC_ADD_NEW_I8;
+ else
+ g_assert_not_reached ();
+ MONO_INST_NEW (cfg, ins, opcode);
MONO_INST_NEW (cfg, ins_iconst, OP_ICONST);
ins_iconst->inst_c0 = -1;
ins->inst_i0 = args [0];
ins->inst_i1 = ins_iconst;
- } else if (strcmp (cmethod->name, "Exchange") == 0 &&
- fsig->params [0]->type == MONO_TYPE_I4) {
- MONO_INST_NEW (cfg, ins, OP_ATOMIC_EXCHANGE_I4);
+ /* FIXME: */
+ } else if (strcmp (cmethod->name, "Exchange") == 0) {
+ guint32 opcode = 0;
+
+ if (fsig->params [0]->type == MONO_TYPE_I4)
+ opcode = OP_ATOMIC_EXCHANGE_I4;
+ else if ((fsig->params [0]->type == MONO_TYPE_I8) ||
+ (fsig->params [0]->type == MONO_TYPE_I) ||
+ (fsig->params [0]->type == MONO_TYPE_OBJECT))
+ opcode = OP_ATOMIC_EXCHANGE_I8;
+ else
+ return NULL;
+
+ MONO_INST_NEW (cfg, ins, opcode);
ins->inst_i0 = args [0];
ins->inst_i1 = args [1];
- } else if (strcmp (cmethod->name, "Add") == 0 &&
- fsig->params [0]->type == MONO_TYPE_I4) {
- MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_I4);
+ } else if (strcmp (cmethod->name, "Add") == 0) {
+ guint32 opcode = 0;
+
+ if (fsig->params [0]->type == MONO_TYPE_I4)
+ opcode = OP_ATOMIC_ADD_I4;
+ else if (fsig->params [0]->type == MONO_TYPE_I8)
+ opcode = OP_ATOMIC_ADD_I8;
+ else
+ g_assert_not_reached ();
+
+ MONO_INST_NEW (cfg, ins, opcode);
ins->inst_i0 = args [0];
ins->inst_i1 = args [1];
+ } else if ((strcmp (cmethod->name, "Read") == 0 &&
+ (fsig->params [0]->type == MONO_TYPE_I8))) {
+ MONO_INST_NEW (cfg, ins, CEE_LDIND_I8);
+ ins->inst_i0 = args [0];
}
}
return ins;
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));
}
/*========================= 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 ========================*/