if(is_Proj(n)) {
ir_node *irn;
- assert(pos == -1 && "Illegal pos for a Proj");
*node = irn = get_Proj_pred(n);
if(is_Proj(irn)) {
assert(get_irn_mode(irn) == mode_T);
return 0;
}
+static be_node_attr_t *retrieve_irn_attr(const ir_node *irn, int *the_pos)
+{
+ int dummy;
+ be_node_attr_t *res = NULL;
+ int *pos = the_pos ? the_pos : &dummy;
+
+ *pos = -1;
+ if(is_Proj(irn)) {
+ ir_node *pred = get_Proj_pred(irn);
+ int p = get_Proj_proj(irn);
+
+ if(is_be_node(pred)) {
+ assert(get_irn_mode(pred) == mode_T);
+ *pos = p;
+ res = get_irn_attr(pred);
+ assert(p >= 0 && p < res->max_reg_data && "illegal proj number");
+ }
+ }
+
+ else if(is_be_node(irn) && get_irn_mode(irn) != mode_T) {
+ be_node_attr_t *a = get_irn_attr(irn);
+ if(a->max_reg_data > 0) {
+ res = a;
+ *pos = 0;
+ }
+ }
+
+ return res;
+}
+
+static be_reg_data_t *retrieve_reg_data(const ir_node *irn)
+{
+ int pos;
+ be_node_attr_t *a = retrieve_irn_attr(irn, &pos);
+ return a ? &a->reg_data[pos] : NULL;
+}
+
static void
be_node_set_irn_reg(const void *_self, ir_node *irn, const arch_register_t *reg)
{
- int out_pos;
- be_node_attr_t *a;
+ be_reg_data_t *r = retrieve_reg_data(irn);
- out_pos = redir_proj((const ir_node **) &irn, -1);
- a = get_irn_attr(irn);
-
- assert(is_be_node(irn));
- assert(out_pos < a->max_reg_data && "position too high");
- a->reg_data[out_pos].reg = reg;
+ if(r)
+ r->reg = reg;
}
int i;
ir_node *frame = get_irg_frame(irg);
const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
- ir_node *irn = new_ir_node(NULL, irg, bl, op_be_MemPerm, mode_T, n, in);
+ ir_node *irn;
+ const arch_register_t *sp = arch_env->isa->sp;
be_memperm_attr_t *attr;
+ ir_node **real_in;
- init_node_attr(irn, n);
+ real_in = alloca((n+1) * sizeof(real_in[0]));
+ real_in[0] = frame;
+ memcpy(&real_in[1], in, n * sizeof(real_in[0]));
+
+ irn = new_ir_node(NULL, irg, bl, op_be_MemPerm, mode_T, n+1, real_in);
+
+ init_node_attr(irn, n + 1);
+ be_node_set_reg_class(irn, 0, sp->reg_class);
for(i = 0; i < n; ++i) {
- be_node_set_reg_class(irn, i, cls_frame);
+ be_node_set_reg_class(irn, i + 1, cls_frame);
be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
}
attr = get_irn_attr(irn);
- attr->in_entities = obstack_alloc(irg->obst, n*sizeof(attr->in_entities[0]));
- memset(attr->in_entities, 0, n*sizeof(attr->in_entities[0]));
+ attr->in_entities = obstack_alloc(irg->obst, n * sizeof(attr->in_entities[0]));
+ memset(attr->in_entities, 0, n * sizeof(attr->in_entities[0]));
attr->out_entities = obstack_alloc(irg->obst, n*sizeof(attr->out_entities[0]));
memset(attr->out_entities, 0, n*sizeof(attr->out_entities[0]));
irn = new_ir_node(NULL, irg, bl, op_be_AddSP, mode_T, be_pos_AddSP_last, in);
a = init_node_attr(irn, be_pos_AddSP_last);
- be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
+ be_node_set_flags(irn, OUT_POS(pn_be_AddSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
/* Set output constraint to stack register. */
be_set_constr_single_reg(irn, be_pos_AddSP_old_sp, sp);
be_node_set_reg_class(irn, be_pos_AddSP_size, arch_register_get_class(sp));
- be_set_constr_single_reg(irn, OUT_POS(0), sp);
+ be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
a->reg_data[pn_be_AddSP_res].reg = sp;
return irn;
}
}
-entity *be_get_frame_entity(const ir_node *irn)
+entity* be_get_frame_entity(const ir_node *irn)
{
if(be_has_frame_entity(irn)) {
be_frame_attr_t *a = get_irn_attr(irn);
return NULL;
}
-void be_set_frame_entity(const ir_node *irn, entity* ent)
-{
- be_frame_attr_t *a;
-
- assert(be_has_frame_entity(irn));
-
- a = get_irn_attr(irn);
- a->ent = ent;
-}
-
void be_set_MemPerm_in_entity(const ir_node *irn, int n, entity *ent)
{
be_memperm_attr_t *attr = get_irn_attr(irn);
assert(be_is_MemPerm(irn));
- assert(n < get_irn_arity(irn));
+ assert(n < be_get_MemPerm_entity_arity(irn));
attr->in_entities[n] = ent;
}
be_memperm_attr_t *attr = get_irn_attr(irn);
assert(be_is_MemPerm(irn));
- assert(n < get_irn_arity(irn));
+ assert(n < be_get_MemPerm_entity_arity(irn));
return attr->in_entities[n];
}
be_memperm_attr_t *attr = get_irn_attr(irn);
assert(be_is_MemPerm(irn));
- assert(n < get_irn_arity(irn));
+ assert(n < be_get_MemPerm_entity_arity(irn));
attr->out_entities[n] = ent;
}
be_memperm_attr_t *attr = get_irn_attr(irn);
assert(be_is_MemPerm(irn));
- assert(n < get_irn_arity(irn));
+ assert(n < be_get_MemPerm_entity_arity(irn));
return attr->out_entities[n];
}
+int be_get_MemPerm_entity_arity(const ir_node *irn)
+{
+ return get_irn_arity(irn) - 1;
+}
+
static void be_limited(void *data, bitset_t *bs)
{
be_req_t *req = data;
const arch_register_t *
be_node_get_irn_reg(const void *_self, const ir_node *irn)
{
- int out_pos;
- be_node_attr_t *a;
-
- out_pos = redir_proj((const ir_node **) &irn, -1);
- a = get_irn_attr(irn);
-
- assert(is_be_node(irn));
- assert(out_pos < a->max_reg_data && "position too high");
-
- return a->reg_data[out_pos].reg;
+ be_reg_data_t *r = retrieve_reg_data(irn);
+ return r ? r->reg : NULL;
}
static arch_irn_class_t be_node_classify(const void *_self, const ir_node *irn)
XXX(StackParam, stackparam);
#undef XXX
default:
- return 0;
+ return arch_irn_class_normal;
}
return 0;
static arch_irn_flags_t be_node_get_flags(const void *_self, const ir_node *irn)
{
- int out_pos;
- be_node_attr_t *a;
-
- out_pos = redir_proj((const ir_node **) &irn, -1);
- a = get_irn_attr(irn);
-
- assert(is_be_node(irn));
- assert(out_pos < a->max_reg_data && "position too high");
-
- return a->reg_data[out_pos].req.flags;
+ be_reg_data_t *r = retrieve_reg_data(irn);
+ return r ? r->req.flags : 0;
}
static entity *be_node_get_frame_entity(const void *self, const ir_node *irn)
return be_get_frame_entity(irn);
}
+static void be_node_set_frame_entity(const void *self, ir_node *irn, entity *ent)
+{
+ be_frame_attr_t *a;
+
+ assert(be_has_frame_entity(irn));
+
+ a = get_irn_attr(irn);
+ a->ent = ent;
+}
+
static void be_node_set_frame_offset(const void *self, ir_node *irn, int offset)
{
if(be_has_frame_entity(irn)) {
be_node_classify,
be_node_get_flags,
be_node_get_frame_entity,
- be_node_set_frame_offset
+ be_node_set_frame_entity,
+ be_node_set_frame_offset,
+ NULL, /* get_inverse */
+ NULL, /* get_op_estimated_cost */
+ NULL, /* possible_memory_operand */
+ NULL, /* perform_memory_operand */
};
static const arch_irn_ops_t be_node_irn_ops = {
return NULL;
}
+static void phi_set_frame_entity(const void *_self, ir_node *irn, entity *ent)
+{
+}
+
static void phi_set_frame_offset(const void *_self, ir_node *irn, int bias)
{
}
phi_classify,
phi_get_flags,
phi_get_frame_entity,
- phi_set_frame_offset
+ phi_set_frame_entity,
+ phi_set_frame_offset,
+ NULL, /* get_inverse */
+ NULL, /* get_op_estimated_cost */
+ NULL, /* possible_memory_operand */
+ NULL, /* perform_memory_operand */
};
static const arch_irn_handler_t phi_irn_handler = {
case beo_MemPerm:
{
int i;
- for(i = 0; i < get_irn_arity(irn); ++i) {
+ for(i = 0; i < be_get_MemPerm_entity_arity(irn); ++i) {
entity *in, *out;
in = be_get_MemPerm_in_entity(irn, i);
out = be_get_MemPerm_out_entity(irn, i);