gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
- guint32 size, i;
+ guint32 size;
MonoClass *klass;
MonoMarshalType *info;
- gboolean is_hfa = TRUE;
- guint32 hfa_type = 0;
+ //gboolean is_hfa = TRUE;
+ //guint32 hfa_type = 0;
klass = mono_class_from_mono_type (type);
if (type->type == MONO_TYPE_TYPEDBYREF)
ins = bb->code;
- if (bb->max_ireg > cfg->rs->next_vireg)
- cfg->rs->next_vireg = bb->max_ireg;
- if (bb->max_freg > cfg->rs->next_vfreg)
- cfg->rs->next_vfreg = bb->max_freg;
+ if (bb->max_vreg > cfg->rs->next_vreg)
+ cfg->rs->next_vreg = bb->max_vreg;
/*
* FIXME: Need to add more instructions, but the current machine
bb->last_ins = last_ins;
- bb->max_ireg = cfg->rs->next_vireg;
- bb->max_freg = cfg->rs->next_vfreg;
+ bb->max_vreg = cfg->rs->next_vreg;
}
/*------------------------------------------------------------------*/
for (i = 0; i < sig->param_count + sig->hasthis; ++i)
{
ArgInfo *ainfo = &cinfo->args [i];
- MonoInst *inst = cfg->varinfo [i];
+ MonoInst *inst = cfg->args [i];
switch(ainfo->storage)
{
for (i = 0; i < sig->param_count + sig->hasthis; ++i)
{
ArgInfo *ainfo = &cinfo->args [i];
- MonoInst *inst = cfg->varinfo [i];
+ MonoInst *inst = cfg->args [i];
int j;
switch(ainfo->storage)
offset = cfg->arch.reg_save_area_offset;
/*
- for (i = 0; i < MONO_MAX_IREGS; ++i)
+ for (i = 0; i < MONO_MAX_VREGS; ++i)
if (ALPHA_IS_CALLEE_SAVED_REG (i) &&
(cfg->used_int_regs & (1 << i)) &&
!( ALPHA_ARGS_REGS & (1 << i)) )
CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl] dreg=%d, sreg1=%d, sreg2=%d\n",
ins->dreg, ins->sreg1, ins->sreg2);
alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_addl_(code, ins->dreg, 0, ins->dreg);
break;
case OP_ISHL_IMM:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl_imm] dreg=%d, sreg1=%d, const=%ld\n",
ins->dreg, ins->sreg1, ins->inst_imm);
alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg);
+ alpha_addl_(code, ins->dreg, 0, ins->dreg);
break;
case OP_SHL_IMM:
// Later check different rounding and exc modes
CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_add] sreg1=%d, sreg2=%d, dreg=%d\n",
ins->sreg1, ins->sreg2, ins->dreg);
- alpha_addt(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_addt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_trapb(code);
break;
case OP_FSUB:
// Later check different rounding and exc modes
CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_sub] sreg1=%d, sreg2=%d, dreg=%d\n",
ins->sreg1, ins->sreg2, ins->dreg);
- alpha_subt(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_subt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_trapb(code);
break;
case OP_FMUL:
break;
case OP_ALPHA_CMP_IMM_ULE:
- CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ule] sreg1=%d, const=%0lX, dreg=%\d\n",
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ule] sreg1=%d, const=%0lX, dreg=%d\n",
ins->sreg1, ins->inst_imm, ins->dreg);
alpha_cmpule_(code, ins->sreg1, ins->inst_imm, alpha_at);
break;
case OP_ALPHA_CMP_IMM_LE:
- CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_le] sreg1=%d, const=%0lX, dreg=%\d\n",
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_le] sreg1=%d, const=%0lX, dreg=%d\n",
ins->sreg1, ins->inst_imm, ins->dreg);
alpha_cmple_(code, ins->sreg1, ins->inst_imm, alpha_at);
break;
alpha_ldt(code, ins->dreg, alpha_sp, 0);
alpha_lda(code, alpha_sp, alpha_sp, 8);
alpha_cvtqs(code, ins->dreg, ins->dreg);
+ alpha_trapb(code);
break;
case CEE_CONV_R8:
alpha_ldt(code, ins->dreg, alpha_sp, 0);
alpha_lda(code, alpha_sp, alpha_sp, 8);
alpha_cvtqt(code, ins->dreg, ins->dreg);
+ alpha_trapb(code);
break;
case OP_FCONV_TO_R4:
// Convert 64 bit float to 32 bit float (T -> S)
CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_r4] sreg=%d, dreg=%d\n",
ins->sreg1, ins->dreg);
- alpha_cvtts(code, ins->sreg1, ins->dreg);
+ alpha_cvtts_su(code, ins->sreg1, ins->dreg);
+ alpha_trapb(code);
break;
case OP_LOCALLOC:
// top of stack is used for call params
CFG_DEBUG(4) g_print("ALPHA_CHECK: [localloc] sreg=%d, dreg=%d\n",
ins->sreg1, ins->dreg);
- alpha_addq_(code, ins->sreg1, (MONO_ARCH_FRAME_ALIGNMENT - 1), ins->sreg1);
- alpha_and_(code, ins->sreg1, ~(MONO_ARCH_FRAME_ALIGNMENT - 1), ins->sreg1);
+
+ alpha_addq_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1);
+ alpha_bic_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1);
+ if (ins->flags & MONO_INST_INIT)
+ alpha_mov1(code, ins->sreg1, ins->sreg2);
+
alpha_subq(code, alpha_sp, ins->sreg1, alpha_sp);
- alpha_lda(code, ins->dreg, alpha_zero, (cfg->arch.params_stack_size));
- alpha_addq(code, alpha_sp, ins->dreg, ins->dreg);
+ if (cfg->arch.params_stack_size > 0)
+ {
+ alpha_lda(code, ins->dreg, alpha_zero,
+ (cfg->arch.params_stack_size));
+ alpha_addq(code, alpha_sp, ins->dreg, ins->dreg);
+ }
+ else
+ alpha_mov1(code, alpha_sp, ins->dreg);
+
+ if (ins->flags & MONO_INST_INIT)
+ {
+ // TODO: Optimize it later
+ alpha_lda(code, ins->sreg2, ins->sreg2,
+ -(MONO_ARCH_LOCALLOC_ALIGNMENT));
+ alpha_blt(code, ins->sreg2, 3);
+ alpha_addq(code, ins->sreg2, ins->dreg, alpha_at);
+ alpha_stq(code, alpha_zero, alpha_at, 0);
+ alpha_br(code, alpha_zero, -5);
+ }
+
break;
case OP_MOVE:
EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
break;
+ case OP_FBGE:
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbge] [");
+ alpha_fbne(code, (alpha_at+1), 1);
+ EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
+ break;
+
case OP_FBLE_UN:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble_un] [");
alpha_fbeq(code, (alpha_at+1), 1);
EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
break;
+ case OP_FBLE:
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble] [");
+ alpha_fbne(code, (alpha_at+1), 1);
+ EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
+ break;
+
case OP_FBLT_UN:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt_un] [");
alpha_fbeq(code, (alpha_at+1), 1);
EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
break;
+ case OP_FBLT:
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt] [");
+ alpha_fbne(code, (alpha_at+1), 1);
+ EMIT_ALPHA_BRANCH(ins, alpha_at, fbne);
+ break;
+
case OP_FBGT_UN:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt_un] [");
alpha_fbeq(code, (alpha_at+1), 1);
EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
break;
+ case OP_FBGT:
+ CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt] [");
+ alpha_fbne(code, (alpha_at+1), 1);
+ EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq);
+ break;
+
case OP_IBEQ:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [ibeq] [");
EMIT_ALPHA_BRANCH(ins, alpha_at, beq);
ins->inst_c0 = (char *)code - (char *)cfg->native_code;
break;
- case CEE_BR:
+ case OP_BR:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [br] target: %p, next: %p, curr: %p, last: %p [",
ins->inst_target_bb, bb->next_bb, ins, bb->last_ins);
}
break;
- case CEE_ENDFINALLY:
+ case OP_ENDFINALLY:
{
// Keep in sync with start_handler
CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfinally] basereg=%d, offset=%0lx\n",
alpha_ret(code, alpha_ra, 1);
break;
- case CEE_THROW:
+ case OP_THROW:
CFG_DEBUG(4) g_print("ALPHA_CHECK: [throw] sreg1=%0x\n",
ins->sreg1);
alpha_mov1(code, ins->sreg1, alpha_a0);
(gpointer)"mono_arch_rethrow_exception");
break;
- case CEE_JMP:
+ case OP_JMP:
{
/*
* Note: this 'frame destruction' logic is useful for tail calls,
CFG_DEBUG(4) g_print("ALPHA_CHECK: [mb]\n");
alpha_mb(code);
break;
-
+
+ case OP_CKFINITE:
+ // Float register contains a value which we need to check
+ {
+ double ni = -1.0 / 0.0;
+ double pi = 1.0 / 0.0;
+ AlphaGotData ge_data;
+
+ CFG_DEBUG(4) g_print("ALPHA_TODO: [chfinite] sreg1=%d\n", ins->sreg1);
+ alpha_cmptun_su(code, ins->sreg1, ins->sreg1, alpha_at);
+ alpha_trapb(code);
+ EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+
+ // Negative infinity
+ ge_data.data.d = ni;
+ add_got_entry(cfg, GT_DOUBLE, ge_data,
+ (char *)code - (char *)cfg->native_code,
+ MONO_PATCH_INFO_NONE, 0);
+ alpha_ldt(code, alpha_at, alpha_gp, 0);
+
+ alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at);
+ alpha_trapb(code);
+
+ EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+
+ // Positive infinity
+ ge_data.data.d = pi;
+ add_got_entry(cfg, GT_DOUBLE, ge_data,
+ (char *)code - (char *)cfg->native_code,
+ MONO_PATCH_INFO_NONE, 0);
+ alpha_ldt(code, alpha_at, alpha_gp, 0);
+
+ alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at);
+ alpha_trapb(code);
+
+ EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException");
+ }
+ break;
+ case OP_FDIV:
+ CFG_DEBUG(4) g_print("ALPHA_TODO: [fdiv] dest=%d, sreg1=%d, sreg2=%d\n",
+ ins->dreg, ins->sreg1, ins->sreg2);
+ alpha_divt_su(code, ins->sreg1, ins->sreg2, ins->dreg);
+ alpha_trapb(code);
+
+ break;
default:
g_warning ("unknown opcode %s in %s()\n",
mono_inst_name (ins->opcode), __FUNCTION__);
if ((i >= sig->hasthis) &&
(MONO_TYPE_ISSTRUCT(arg_type)))
{
- gint align;
+ guint align;
guint32 size;
if (arg_type->type == MONO_TYPE_TYPEDBYREF) {
/*========================= End of Function ========================*/
-static gboolean
-is_regsize_var (MonoType *t)
-{
- if (t->byref)
- return TRUE;
-
- t = mono_type_get_underlying_type (t);
- switch (t->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_BOOLEAN:
- return TRUE;
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return TRUE;
- case MONO_TYPE_VALUETYPE:
- return FALSE;
- }
-
- return FALSE;
-}
-
-
-
-
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_get_allocatable_int_vars */
for (i = 0; i < sig->param_count + sig->hasthis; ++i)
{
- MonoInst *ins = cfg->varinfo [i];
+ MonoInst *ins = cfg->args [i];
ArgInfo *ainfo = &cinfo->args [i];
(ins->opcode != OP_LOCAL && ins->opcode != OP_ARG))
continue;
- if (is_regsize_var (ins->inst_vtype))
+ if (mono_is_regsize_var (ins->inst_vtype))
{
g_assert (MONO_VARINFO (cfg, i)->reg == -1);
g_assert (i == vmv->idx);
for (i = 0; i < n; ++i)
{
- inst = cfg->varinfo [i];
+ inst = cfg->args [i];
if (inst->opcode == OP_REGVAR)
{
// Reserve space for method params
for (i = 0; i < sig->param_count + sig->hasthis; ++i)
{
- inst = cfg->varinfo [i];
+ inst = cfg->args [i];
if (inst->opcode != OP_REGVAR)
{
pc, regs);
// Check if we have parameters on stack
- if (pc[-2] & 0xFFFF0000 == 0x23DE0000) // lda sp,-n(sp)
+ if ((pc[-2] & 0xFFFF0000) == 0x23DE0000) // lda sp,-n(sp)
start_index = -3;
// Check for (call_membase):