}
ARR_APP1(ir_node *, env->calls, low_call);
+ /* create new stack pointer */
+ curr_sp = new_r_Proj(irg, bl, low_call, get_irn_mode(curr_sp),
+ pn_be_Call_sp);
+ be_set_constr_single_reg(low_call, BE_OUT_POS(pn_be_Call_sp), sp);
+ arch_set_irn_register(arch_env, curr_sp, sp);
+ be_node_set_flags(low_call, BE_OUT_POS(pn_be_Call_sp),
+ arch_irn_flags_ignore | arch_irn_flags_modify_sp);
+
for(i = 0; i < n_res; ++i) {
int pn;
ir_node *proj = res_projs[i];
/* memorize the register in the link field. we need afterwards to set the register class of the keep correctly. */
be_set_constr_single_reg(low_call, BE_OUT_POS(curr_res_proj), reg);
- arch_set_irn_register(env->birg->main_env->arch_env, proj, reg);
+ arch_set_irn_register(arch_env, proj, reg);
/* a call can produce ignore registers, in this case set the flag and register for the Proj */
if (arch_register_type_is(reg, ignore)) {
if (! no_alloc) {
/* the callee pops the shadow parameter */
if(get_method_calling_convention(mt) & cc_compound_ret) {
- stack_size -= get_mode_size_bytes(mode_P_data);
+ unsigned size = get_mode_size_bytes(mode_P_data);
+ stack_size -= size;
+ be_Call_set_pop(low_call, size);
}
curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size);
- add_irn_dep(curr_sp, mem_proj);
+ //add_irn_dep(curr_sp, mem_proj);
}
}
#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;
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;
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];
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,
unsigned pop, int n, ir_node *in[])
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;
}
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 -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;