#define OUT_POS(x) (-((x) + 1))
-/* Sometimes we want to put const nodes into get_irn_generic_attr ... */
-#define get_irn_attr(irn) get_irn_generic_attr((ir_node *) (irn))
+#define get_irn_attr(irn) get_irn_generic_attr(irn)
+#define get_irn_attr_const(irn) get_irn_generic_attr_const(irn)
static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O');
typedef struct {
be_node_attr_t node_attr;
int num_ret_vals; /**< number of return values */
+ unsigned pop; /**< number of bytes that should be popped */
} be_return_attr_t;
/** The be_Stack attribute type. */
typedef struct {
be_node_attr_t node_attr;
ir_entity *ent; /**< The called entity if this is a static call. */
+ unsigned pop;
ir_type *call_tp; /**< The call type, copied from the original Call node. */
} be_call_attr_t;
ir_op *op_be_IncSP;
ir_op *op_be_AddSP;
ir_op *op_be_SubSP;
-ir_op *op_be_SetSP;
ir_op *op_be_RegParams;
ir_op *op_be_FrameAddr;
ir_op *op_be_Barrier;
if (a_attr->num_ret_vals != b_attr->num_ret_vals)
return 1;
+ if (a_attr->pop != b_attr->pop)
+ return 1;
return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
}
static INLINE be_req_t *get_be_req(const ir_node *node, int pos)
{
int idx;
- be_node_attr_t *attr;
+ const be_node_attr_t *attr;
be_reg_data_t *rd;
assert(is_be_node(node));
- attr = get_irn_attr(node);
+ attr = get_irn_attr_const(node);
if(pos < 0) {
idx = -(pos + 1);
op_be_AddSP = new_ir_op(beo_base + beo_AddSP, "be_AddSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_SubSP = new_ir_op(beo_base + beo_SubSP, "be_SubSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_IncSP = new_ir_op(beo_base + beo_IncSP, "be_IncSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_stack_attr_t), &be_node_op_ops);
- op_be_SetSP = new_ir_op(beo_base + beo_SetSP, "be_SetSP", op_pin_state_pinned, N, oparity_binary, 0, sizeof(be_stack_attr_t), &be_node_op_ops);
op_be_RegParams = new_ir_op(beo_base + beo_RegParams, "be_RegParams", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_FrameAddr = new_ir_op(beo_base + beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Barrier = new_ir_op(beo_base + beo_Barrier, "be_Barrier", op_pin_state_pinned, N, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_AddSP->ops.node_cmp_attr = node_cmp_attr;
set_op_tag(op_be_SubSP, &be_node_tag);
op_be_SubSP->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_SetSP, &be_node_tag);
- op_be_SetSP->ops.node_cmp_attr = Stack_cmp_attr;
set_op_tag(op_be_IncSP, &be_node_tag);
op_be_IncSP->ops.node_cmp_attr = Stack_cmp_attr;
set_op_tag(op_be_RegParams, &be_node_tag);
static be_reg_data_t *retrieve_reg_data(const ir_node *node)
{
- be_node_attr_t *attr;
+ const be_node_attr_t *attr;
int pos = 0;
if(is_Proj(node)) {
}
assert(is_be_node(node));
- attr = get_irn_attr(node);
+ attr = get_irn_attr_const(node);
assert(pos >= 0 && pos < ARR_LEN(attr->reg_data) && "illegal proj number");
return &attr->reg_data[pos];
void be_Perm_reduce(ir_node *perm, int new_size, int *map)
{
ir_graph *irg = get_irn_irg(perm);
- int n = get_irn_arity(perm);
- be_reg_data_t *old_data = xmalloc(n * sizeof(old_data[0]));
+ int arity = get_irn_arity(perm);
+ be_reg_data_t *old_data = alloca(arity * sizeof(old_data[0]));
be_node_attr_t *attr = get_irn_attr(perm);
- ir_node **new_in = NEW_ARR_D(ir_node *, irg->obst, new_size + 1);
+ ir_node **new_in = NEW_ARR_D(ir_node *, irg->obst, new_size);
int i;
assert(be_is_Perm(perm));
- assert(new_size <= n);
+ assert(new_size <= arity);
/* save the old register data */
- memcpy(old_data, attr->reg_data, n * sizeof(old_data[0]));
+ memcpy(old_data, attr->reg_data, arity * sizeof(old_data[0]));
/* compose the new in array and set the new register data directly in place */
- for (i = 0; i < n; ++i) {
+ for (i = 0; i < new_size; ++i) {
int idx = map[i];
- if (idx >= 0) {
- new_in[idx] = get_irn_n(perm, i);
- attr->reg_data[idx] = old_data[i];
- }
+ new_in[i] = get_irn_n(perm, idx);
+ attr->reg_data[i] = old_data[idx];
}
- free(old_data);
set_irn_in(perm, new_size, new_in);
}
req = get_req(res, OUT_POS(0));
req->cls = cls;
req->type = arch_register_req_type_should_be_same;
- req->other_same = 0;
+ req->other_same = 1U << 0;
return res;
}
a = init_node_attr(irn, (n_outs > real_n ? n_outs : real_n));
a->ent = NULL;
a->call_tp = call_tp;
+ a->pop = 0;
return irn;
}
/* Gets the call entity or NULL if this is no static call. */
ir_entity *be_Call_get_entity(const ir_node *call) {
- be_call_attr_t *a = get_irn_attr(call);
+ const be_call_attr_t *a = get_irn_attr_const(call);
assert(be_is_Call(call));
return a->ent;
}
/* Gets the call type. */
ir_type *be_Call_get_type(ir_node *call) {
- be_call_attr_t *a = get_irn_attr(call);
+ const be_call_attr_t *a = get_irn_attr_const(call);
assert(be_is_Call(call));
return a->call_tp;
}
a->call_tp = call_tp;
}
+void be_Call_set_pop(ir_node *call, unsigned pop) {
+ be_call_attr_t *a = get_irn_attr(call);
+ a->pop = pop;
+}
+
+unsigned be_Call_get_pop(const ir_node *call) {
+ const be_call_attr_t *a = get_irn_attr_const(call);
+ return a->pop;
+}
+
/* Construct a new be_Return. */
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res,
- int n, ir_node *in[])
+ unsigned pop, int n, ir_node *in[])
{
be_return_attr_t *a;
ir_node *res;
a = get_irn_attr(res);
a->num_ret_vals = n_res;
+ a->pop = pop;
return res;
}
/* Returns the number of real returns values */
-int be_Return_get_n_rets(ir_node *ret)
+int be_Return_get_n_rets(const ir_node *ret)
{
- be_return_attr_t *a = get_irn_attr(ret);
+ const be_return_attr_t *a = get_irn_generic_attr_const(ret);
return a->num_ret_vals;
}
+unsigned be_Return_get_pop(const ir_node *ret)
+{
+ const be_return_attr_t *a = get_irn_generic_attr_const(ret);
+ return a->pop;
+}
+
int be_Return_append_node(ir_node *ret, ir_node *node)
{
int pos;
return irn;
}
-ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl,
- ir_node *old_sp, ir_node *op, ir_node *mem)
-{
- be_node_attr_t *a;
- ir_node *irn;
- ir_node *in[3];
-
- in[0] = mem;
- in[1] = old_sp;
- in[2] = op;
- irn = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
- a = init_node_attr(irn, 3);
-
- be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
-
- /* Set output constraint to stack register. */
- be_set_constr_single_reg(irn, OUT_POS(0), sp);
- be_node_set_reg_class(irn, be_pos_AddSP_size, sp->reg_class);
- be_node_set_reg_class(irn, be_pos_AddSP_old_sp, sp->reg_class);
-
- return irn;
-}
-
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
{
ir_node *res;
int be_is_Call (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Call ; }
int be_is_Return (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Return ; }
int be_is_IncSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_IncSP ; }
-int be_is_SetSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP ; }
int be_is_AddSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP ; }
int be_is_SubSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP ; }
int be_is_RegParams (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams ; }
ir_entity *be_get_frame_entity(const ir_node *irn)
{
if (be_has_frame_entity(irn)) {
- be_frame_attr_t *a = get_irn_attr(irn);
+ const be_frame_attr_t *a = get_irn_attr_const(irn);
return a->ent;
}
return NULL;
{
assert(is_be_node(irn));
if (be_has_frame_entity(irn)) {
- be_frame_attr_t *a = get_irn_attr(irn);
+ const be_frame_attr_t *a = get_irn_attr_const(irn);
return a->offset;
}
return 0;
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
{
- be_memperm_attr_t *attr = get_irn_attr(irn);
+ const be_memperm_attr_t *attr = get_irn_attr_const(irn);
assert(be_is_MemPerm(irn));
assert(n < be_get_MemPerm_entity_arity(irn));
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
{
- be_memperm_attr_t *attr = get_irn_attr(irn);
+ const be_memperm_attr_t *attr = get_irn_attr_const(irn);
assert(be_is_MemPerm(irn));
assert(n < be_get_MemPerm_entity_arity(irn));
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
{
- be_memperm_attr_t *attr = get_irn_attr(irn);
+ const be_memperm_attr_t *attr = get_irn_attr_const(irn);
assert(be_is_MemPerm(irn));
assert(n < be_get_MemPerm_entity_arity(irn));
ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
{
- be_memperm_attr_t *attr = get_irn_attr(irn);
+ const be_memperm_attr_t *attr = get_irn_attr_const(irn);
assert(be_is_MemPerm(irn));
assert(n < be_get_MemPerm_entity_arity(irn));
bereq->flags = flags;
}
+void be_node_add_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
+{
+ be_req_t *bereq = get_be_req(irn, pos);
+ bereq->flags |= flags;
+}
+
void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls)
{
arch_register_req_t *req = get_req(irn, pos);
int be_get_IncSP_offset(const ir_node *irn)
{
- be_stack_attr_t *a = get_irn_attr(irn);
+ const be_stack_attr_t *a = get_irn_attr_const(irn);
assert(be_is_IncSP(irn));
return a->offset;
}
-ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
+ir_node *be_spill(const arch_env_t *arch_env, ir_node *block, ir_node *irn)
{
- ir_node *bl = get_nodes_block(irn);
- ir_graph *irg = get_irn_irg(bl);
+ ir_graph *irg = get_irn_irg(block);
ir_node *frame = get_irg_frame(irg);
const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, irn, -1);
const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
ir_node *spill;
- spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
+ spill = be_new_Spill(cls, cls_frame, irg, block, frame, irn);
return spill;
}
static const
arch_register_req_t *get_out_reg_req(const ir_node *irn, int out_pos)
{
- const be_node_attr_t *a = get_irn_attr(irn);
+ const be_node_attr_t *a = get_irn_attr_const(irn);
if(out_pos >= ARR_LEN(a->reg_data)) {
return arch_no_register_req;
static const
arch_register_req_t *get_in_reg_req(const ir_node *irn, int pos)
{
- const be_node_attr_t *a = get_irn_attr(irn);
+ const be_node_attr_t *a = get_irn_attr_const(irn);
if(pos >= get_irn_arity(irn) || pos >= ARR_LEN(a->reg_data))
return arch_no_register_req;
static int be_node_get_sp_bias(const void *self, const ir_node *irn)
{
(void) self;
- return be_is_IncSP(irn) ? be_get_IncSP_offset(irn) : 0;
+ if(be_is_IncSP(irn))
+ return be_get_IncSP_offset(irn);
+ if(be_is_Call(irn))
+ return -(int)be_Call_get_pop(irn);
+
+ return 0;
}
/*
*/
static void copy_attr(const ir_node *old_node, ir_node *new_node)
{
- be_node_attr_t *old_attr = get_irn_attr(old_node);
+ const be_node_attr_t *old_attr = get_irn_attr_const(old_node);
be_node_attr_t *new_attr = get_irn_attr(new_node);
struct obstack *obst = get_irg_obstack(get_irn_irg(new_node));
unsigned i, len;