#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;
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);
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];
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;
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));
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;