#define ALPHA_PRINT if (mini_alpha_verbose_level)
-#define NEW_INS(cfg,ins,dest,op) do { \
+#define NEW_INS(cfg,dest,op) do { \
(dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
(dest)->opcode = (op); \
- MONO_INST_LIST_ADD_TAIL (&(dest)->node, &(ins)->node);
+ insert_after_ins (bb, last_ins, (dest)); \
} while (0)
#define NEW_ICONST(cfg,dest,val) do { \
gboolean lmf_addr_key_inited = FALSE;
+MonoBreakpointInfo
+mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
/*====================== End of Global Variables ===================*/
gpointer mono_arch_get_lmf_addr (void);
}
static void
-add_valuetype (MonoGenericSharingContext *ctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
}
}
+static void
+insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert)
+{
+ if (ins == NULL)
+ {
+ ins = bb->code;
+ bb->code = to_insert;
+ to_insert->next = ins;
+ }
+ else
+ {
+ to_insert->next = ins->next;
+ ins->next = to_insert;
+ }
+}
+
static void add_got_entry(MonoCompile *cfg, AlphaGotType ge_type,
AlphaGotData ge_data,
int ip, MonoJumpInfoType type, gconstpointer target)
/*========================= End of Function ========================*/
+// This peephole function is called before "local_regalloc" method
+// TSV_TODO - Check what we need to move here
void
mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb)
{
+ CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE_1 pass\n");
}
+// This peephole function is called after "local_regalloc" method
void
mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
{
- MonoInst *ins, *n;
+ MonoInst *ins, *n, *last_ins = NULL;
+ ins = bb->code;
- CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE pass\n");
+ CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE_2 pass\n");
- MONO_INST_LIST_FOR_EACH_ENTRY_SAFE (ins, n, &bb->ins_list, node) {
- MonoInst *last_ins = mono_inst_list_prev (&ins->node, &bb->ins_list);
+ MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
switch (ins->opcode)
{
case OP_MOVE:
if (ins->dreg == ins->sreg1 &&
ins->dreg != alpha_at)
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
last_ins->dreg != alpha_at &&
ins->dreg == last_ins->sreg1)
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
}
else
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
}
{
if (ins->dreg == last_ins->sreg1)
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
else
{
if (ins->dreg == last_ins->sreg1)
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
else
{
if (ins->dreg == last_ins->dreg)
{
- MONO_DEL_INS (ins);
+ MONO_DELETE_INS (bb, ins);
continue;
}
else
break;
#endif
}
+
+ last_ins = ins;
+ ins = ins->next;
}
+
+ bb->last_ins = last_ins;
}
// Convert to opposite branch opcode
* Converts complex opcodes into simpler ones so that each IR instruction
* corresponds to one machine instruction.
*/
-static void
- mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
+void
+mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
{
- MonoInst *ins, *n, *next, *temp;
+ MonoInst *ins, *n, *temp, *last_ins = NULL;
+ MonoInst *next;
+
+ ins = bb->code;
if (bb->max_vreg > cfg->rs->next_vreg)
cfg->rs->next_vreg = bb->max_vreg;
* cdq.
*/
- MONO_INST_LIST_FOR_EACH_ENTRY_SAFE (ins, n, &bb->ins_list, node) {
+ MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
switch (ins->opcode)
{
case OP_DIV_IMM:
case OP_IDIV_IMM:
case OP_IREM_IMM:
case OP_MUL_IMM:
- NEW_INS (cfg, ins, temp, OP_I8CONST);
+ NEW_INS (cfg, temp, OP_I8CONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
// Instead of compare+b<cond>/fcompare+b<cond>,
// Alpha has compare<cond>+br<cond>/fcompare<cond>+br<cond>
// we need to convert
- next = mono_inst_list_next (&ins->node, &bb->ins_list);
- g_assert(next);
+ next = ins->next;
cvt_cmp_branch(ins, next);
}
case OP_COMPARE_IMM:
if (!alpha_is_imm (ins->inst_imm))
{
- NEW_INS (cfg, ins, temp, OP_I8CONST);
+ NEW_INS (cfg, temp, OP_I8CONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_COMPARE;
ins->sreg2 = temp->dreg;
// We should try to reevaluate new IR opcode
- continue;
+ //continue;
}
- next = mono_inst_list_next (&ins->node, &bb->ins_list);
- g_assert(next);
+ next = ins->next;
cvt_cmp_branch(ins, next);
case OP_ICOMPARE_IMM:
if (!alpha_is_imm (ins->inst_imm))
{
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_ICOMPARE;
ins->sreg2 = temp->dreg;
// We should try to reevaluate new IR opcode
- continue;
+ //continue;
}
- next = mono_inst_list_next (&ins->node, &bb->ins_list);
- g_assert(next);
+ next = ins->next;
cvt_cmp_branch(ins, next);
case OP_STOREI8_MEMBASE_IMM:
if (ins->inst_imm != 0)
{
- NEW_INS (cfg, ins, temp, OP_I8CONST);
+ NEW_INS (cfg, temp, OP_I8CONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_STOREI8_MEMBASE_REG;
if (ins->inst_imm != 0)
{
MonoInst *temp;
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_STOREI4_MEMBASE_REG;
if (ins->inst_imm != 0 || !bwx_supported)
{
MonoInst *temp;
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_STOREI1_MEMBASE_REG;
if (ins->inst_imm != 0 || !bwx_supported)
{
MonoInst *temp;
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
ins->opcode = OP_STOREI2_MEMBASE_REG;
if (!alpha_is_imm(ins->inst_imm))
{
MonoInst *temp;
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
if (!alpha_is_imm(ins->inst_imm))
{
MonoInst *temp;
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int (cfg->rs);
if (!alpha_is_imm(ins->inst_imm))
{
MonoInst *temp;
- NEW_INS(cfg, ins, temp, OP_ICONST);
+ NEW_INS(cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int(cfg->rs);
ins->sreg2 = temp->dreg;
if (!alpha_is_imm(ins->inst_imm))
{
MonoInst *temp;
- NEW_INS(cfg, ins, temp, OP_ICONST);
+ NEW_INS(cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_regstate_next_int(cfg->rs);
ins->sreg2 = temp->dreg;
default:
break;
}
+
+ last_ins = ins;
+ ins = ins->next;
}
+ bb->last_ins = last_ins;
+
bb->max_vreg = cfg->rs->next_vreg;
}
MonoCallInst *call;
guint offset;
unsigned int *code = (unsigned int *)(cfg->native_code + cfg->code_len);
+ MonoInst *last_ins = NULL;
guint last_offset = 0;
int max_len, cpos;
switch (ins->opcode)
{
+ case OP_RELAXED_NOP:
+ break;
case OP_LSHR:
// Shift 64 bit value right
CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr] dreg=%d, sreg1=%d, sreg2=%d\n",
break;
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);
+
if (ins->flags & MONO_INST_BRLABEL)
{
if (ins->inst_i0->inst_c0)
cpos += max_len;
+ last_ins = ins;
last_offset = offset;
- }
+ }
cfg->code_len = ((char *)code) - ((char *)cfg->native_code);
}
MONO_INST_NEW (cfg, arg, OP_OUTARG);
arg->inst_left = sig_arg;
arg->type = STACK_PTR;
- MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+
+ /* prepend, so they get reversed */
+ arg->next = call->out_args;
+ call->out_args = arg;
}
if (is_virtual && i == 0) {
arg->cil_code = in->cil_code;
arg->inst_left = in;
arg->type = in->type;
- MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+ /* prepend, so they get reversed */
+ arg->next = call->out_args;
+ call->out_args = arg;
CFG_DEBUG(3) g_print("ALPHA: Param[%d] - ", i);
add_outarg_reg (cfg, call, set_reg, arg_storage,
dest_reg, load);
- if (&set_reg->node != call->out_args.next)
+ if (set_reg != call->out_args)
{
- MONO_INST_LIST_ADD (&set_reg->node, &call->out_args);
+ set_reg->next = call->out_args;
+ call->out_args = set_reg;
}
}
//outarg->inst_imm = 16 + ainfo->offset + (slot - 8) * 8;
outarg->dreg = ainfo->offset + (slot - 22) * 8;
- if (&outarg->node != call->out_args.next)
+ if (outarg != call->out_args)
{
- MONO_INST_LIST_ADD (&outarg->node, &call->out_args);
+ outarg->next = call->out_args;
+ call->out_args = outarg;
}
}
arg->inst_left = vtaddr;
arg->inst_right = in;
arg->type = in->type;
- MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+
+ /* prepend, so they get reversed */
+ arg->next = call->out_args;
+ call->out_args = arg;
}
else
{
zero_inst->inst_p0 = 0;
arg->inst_left = zero_inst;
arg->type = STACK_PTR;
- MONO_INST_LIST_ADD (&arg->node, &call->out_args);
+ /* prepend, so they get reversed */
+ arg->next = call->out_args;
+ call->out_args = arg;
}
else
/* if the function returns a struct, the called method a
return 0;
}
+gpointer
+mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gssize *regs, guint8 *code)
+{
+ unsigned int *pc = (unsigned int *)code;
+
+ ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_this_arg_from_call] code: %p regs: %p",
+ pc, regs);
+
+ if (MONO_TYPE_ISSTRUCT (sig->ret))
+ return (gpointer)regs [alpha_a1];
+ else
+ return (gpointer)regs [alpha_a0];
+}
+
+gpointer
+mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
+{
+ unsigned int *code, *start;
+ MonoDomain *domain = mono_domain_get ();
+ int i;
+
+ ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_delegate_invoke_impl]");
+
+ /* FIXME: Support more cases */
+ if (MONO_TYPE_ISSTRUCT (sig->ret))
+ return NULL;
+
+ return NULL;
+}
guint32
mono_arch_get_patch_offset (guint8 *code)
{
return 3;
}
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+ /* FIXME: implement */
+ g_assert_not_reached ();
+}