/*
- * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
#include "belive_t.h"
#include "besched_t.h"
#include "benode_t.h"
+#include "bearch_t.h"
#include "beirgmod.h"
#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');
/** The generic be nodes attribute type. */
typedef struct {
- be_reg_data_t *reg_data;
+ be_reg_data_t *reg_data;
} be_node_attr_t;
/** The be_Return nodes attribute type. */
typedef struct {
- be_node_attr_t node_attr;
+ be_node_attr_t node_attr; /**< base attributes of every be node. */
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. */
+/** The be_IncSP attribute type. */
typedef struct {
- be_node_attr_t node_attr;
- int offset; /**< The offset by which the stack shall be expanded/shrinked. */
-} be_stack_attr_t;
+ be_node_attr_t node_attr; /**< base attributes of every be node. */
+ int offset; /**< The offset by which the stack shall be expanded/shrinked. */
+} be_incsp_attr_t;
/** The be_Frame attribute type. */
typedef struct {
- be_node_attr_t node_attr;
+ be_node_attr_t node_attr; /**< base attributes of every be node. */
ir_entity *ent;
int offset;
} be_frame_attr_t;
/** The be_Call attribute type. */
typedef struct {
- be_node_attr_t node_attr;
- ir_entity *ent; /**< The called entity if this is a static call. */
- ir_type *call_tp; /**< The call type, copied from the original Call node. */
+ be_node_attr_t node_attr; /**< base attributes of every be node. */
+ 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;
typedef struct {
- be_node_attr_t node_attr;
+ be_node_attr_t node_attr; /**< base attributes of every be node. */
ir_entity **in_entities;
ir_entity **out_entities;
} be_memperm_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_StackParam;
ir_op *op_be_FrameAddr;
-ir_op *op_be_FrameLoad;
-ir_op *op_be_FrameStore;
ir_op *op_be_Barrier;
+ir_op *op_be_Unwind;
static int beo_base = -1;
#define H irop_flag_highlevel
#define c irop_flag_constlike
#define K irop_flag_keep
-#define M irop_flag_machine
+#define M irop_flag_uses_memory
/**
- * Compare two node attributes.
+ * Compare two be node attributes.
*
* @return zero if both attributes are identically
*/
-static int _node_cmp_attr(be_node_attr_t *a, be_node_attr_t *b) {
+static int _node_cmp_attr(const be_node_attr_t *a, const be_node_attr_t *b) {
int i, len;
- if(ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data))
+ if (ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data))
return 1;
len = ARR_LEN(a->reg_data);
return 0;
}
+/**
+ * Compare the node attributes of two be_node's.
+ *
+ * @return zero if both nodes have identically attributes
+ */
static int node_cmp_attr(ir_node *a, ir_node *b) {
- be_node_attr_t *a_attr = get_irn_attr(a);
- be_node_attr_t *b_attr = get_irn_attr(b);
+ const be_node_attr_t *a_attr = get_irn_attr_const(a);
+ const be_node_attr_t *b_attr = get_irn_attr_const(b);
return _node_cmp_attr(a_attr, b_attr);
}
/**
- * Compare the attributes of two FrameAddr nodes.
+ * Compare the attributes of two be_FrameAddr nodes.
*
- * @return zero if both attributes are identically
+ * @return zero if both nodes have identically attributes
*/
static int FrameAddr_cmp_attr(ir_node *a, ir_node *b) {
- be_frame_attr_t *a_attr = get_irn_attr(a);
- be_frame_attr_t *b_attr = get_irn_attr(b);
+ const be_frame_attr_t *a_attr = get_irn_attr_const(a);
+ const be_frame_attr_t *b_attr = get_irn_attr_const(b);
if (a_attr->ent != b_attr->ent || a_attr->offset != b_attr->offset)
return 1;
- return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
+ return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr);
}
+/**
+ * Compare the attributes of two be_Return nodes.
+ *
+ * @return zero if both nodes have identically attributes
+ */
static int Return_cmp_attr(ir_node *a, ir_node *b) {
- be_return_attr_t *a_attr = get_irn_attr(a);
- be_return_attr_t *b_attr = get_irn_attr(b);
+ const be_return_attr_t *a_attr = get_irn_attr_const(a);
+ const be_return_attr_t *b_attr = get_irn_attr_const(b);
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);
+ return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr);
}
-static int Stack_cmp_attr(ir_node *a, ir_node *b) {
- be_stack_attr_t *a_attr = get_irn_attr(a);
- be_stack_attr_t *b_attr = get_irn_attr(b);
+/**
+ * Compare the attributes of two be_IncSP nodes.
+ *
+ * @return zero if both nodes have identically attributes
+ */
+static int IncSP_cmp_attr(ir_node *a, ir_node *b) {
+ const be_incsp_attr_t *a_attr = get_irn_attr_const(a);
+ const be_incsp_attr_t *b_attr = get_irn_attr_const(b);
if (a_attr->offset != b_attr->offset)
return 1;
- return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
+ return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr);
}
+/**
+ * Compare the attributes of two be_Call nodes.
+ *
+ * @return zero if both nodes have identically attributes
+ */
static int Call_cmp_attr(ir_node *a, ir_node *b) {
- be_call_attr_t *a_attr = get_irn_attr(a);
- be_call_attr_t *b_attr = get_irn_attr(b);
+ const be_call_attr_t *a_attr = get_irn_attr_const(a);
+ const be_call_attr_t *b_attr = get_irn_attr_const(b);
if (a_attr->ent != b_attr->ent ||
a_attr->call_tp != b_attr->call_tp)
return 1;
- return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
+ return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_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);
/* Acquire all needed opcodes. */
beo_base = get_next_ir_opcodes(beo_Last);
- op_be_Spill = new_ir_op(beo_base + beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_Reload = new_ir_op(beo_base + beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_Perm = new_ir_op(beo_base + beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_MemPerm = new_ir_op(beo_base + beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
- op_be_Copy = new_ir_op(beo_base + beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_Keep = new_ir_op(beo_base + beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_CopyKeep = new_ir_op(beo_base + beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_Call = new_ir_op(beo_base + beo_Call, "be_Call", op_pin_state_pinned, F, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops);
- op_be_Return = new_ir_op(beo_base + beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops);
- 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_StackParam = new_ir_op(beo_base + beo_StackParam, "be_StackParam", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_FrameLoad = new_ir_op(beo_base + beo_FrameLoad, "be_FrameLoad", op_pin_state_floats, N, oparity_any, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "be_FrameStore", op_pin_state_floats, N, oparity_any, 0, sizeof(be_frame_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_Spill = new_ir_op(beo_base + beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
+ op_be_Reload = new_ir_op(beo_base + beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
+ op_be_Perm = new_ir_op(beo_base + beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_MemPerm = new_ir_op(beo_base + beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
+ op_be_Copy = new_ir_op(beo_base + beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_Keep = new_ir_op(beo_base + beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_CopyKeep = new_ir_op(beo_base + beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_Call = new_ir_op(beo_base + beo_Call, "be_Call", op_pin_state_pinned, F|M, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops);
+ op_be_Return = new_ir_op(beo_base + beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops);
+ 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_incsp_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_Unwind = new_ir_op(beo_base + beo_Unwind, "be_Unwind", op_pin_state_pinned, X, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
set_op_tag(op_be_Spill, &be_node_tag);
op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
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;
+ op_be_IncSP->ops.node_cmp_attr = IncSP_cmp_attr;
set_op_tag(op_be_RegParams, &be_node_tag);
op_be_RegParams->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_StackParam, &be_node_tag);
- op_be_StackParam->ops.node_cmp_attr = FrameAddr_cmp_attr;
- set_op_tag(op_be_FrameLoad, &be_node_tag);
- op_be_FrameLoad->ops.node_cmp_attr = FrameAddr_cmp_attr;
- set_op_tag(op_be_FrameStore, &be_node_tag);
- op_be_FrameStore->ops.node_cmp_attr = FrameAddr_cmp_attr;
set_op_tag(op_be_FrameAddr, &be_node_tag);
op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
set_op_tag(op_be_Barrier, &be_node_tag);
op_be_Barrier->ops.node_cmp_attr = node_cmp_attr;
+ set_op_tag(op_be_Unwind, &be_node_tag);
+ op_be_Unwind->ops.node_cmp_attr = node_cmp_attr;
}
/**
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 = malloc(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);
}
init_node_attr(irn, n + 1);
be_node_set_reg_class(irn, 0, sp->reg_class);
- for(i = 0; i < n; ++i) {
+ for (i = 0; i < n; ++i) {
be_node_set_reg_class(irn, i + 1, cls_frame);
be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
}
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_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset)
{
- be_stack_attr_t *a;
+ be_incsp_attr_t *a;
ir_node *irn;
ir_node *in[1];
be_node_attr_t *a;
ir_node *irn;
ir_node *in[be_pos_AddSP_last];
+ const arch_register_class_t *class;
in[be_pos_AddSP_old_sp] = old_sp;
in[be_pos_AddSP_size] = sz;
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(pn_be_AddSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
+ be_node_set_flags(irn, OUT_POS(pn_be_AddSP_sp),
+ 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(pn_be_AddSP_res), sp);
- a->reg_data[pn_be_AddSP_res].reg = sp;
+ be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_sp), sp);
+ a->reg_data[pn_be_AddSP_sp].reg = sp;
+
+ class = arch_register_get_class(sp);
+ be_node_set_reg_class(irn, OUT_POS(pn_be_AddSP_res), class);
return irn;
}
irn = new_ir_node(NULL, irg, bl, op_be_SubSP, mode_T, be_pos_SubSP_last, in);
a = init_node_attr(irn, be_pos_SubSP_last);
- be_node_set_flags(irn, OUT_POS(pn_be_SubSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
+ be_node_set_flags(irn, OUT_POS(pn_be_SubSP_sp),
+ arch_irn_flags_ignore | arch_irn_flags_modify_sp);
/* Set output constraint to stack register. */
be_set_constr_single_reg(irn, be_pos_SubSP_old_sp, sp);
be_node_set_reg_class(irn, be_pos_SubSP_size, arch_register_get_class(sp));
- be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_res), sp);
- a->reg_data[pn_be_SubSP_res].reg = sp;
-
- 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_StackParam(const arch_register_class_t *cls, const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_mode *mode, ir_node *frame_pointer, ir_entity *ent)
-{
- be_frame_attr_t *a;
- ir_node *irn;
- ir_node *in[1];
-
- in[0] = frame_pointer;
- irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
- a = init_node_attr(irn, 1);
- a->ent = ent;
-
- be_node_set_reg_class(irn, 0, cls_frame);
- be_node_set_reg_class(irn, OUT_POS(0), cls);
- be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_rematerializable);
+ be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_sp), sp);
+ a->reg_data[pn_be_SubSP_sp].reg = sp;
return irn;
}
return proj;
}
-ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
- ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
-{
- be_frame_attr_t *a;
- ir_node *irn;
- ir_node *in[2];
-
- in[0] = mem;
- in[1] = frame;
- irn = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
- a = init_node_attr(irn, 3);
- a->ent = ent;
- a->offset = 0;
- be_node_set_reg_class(irn, 1, cls_frame);
- be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
- return irn;
-}
-
-ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
- ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
-{
- be_frame_attr_t *a;
- ir_node *irn;
- ir_node *in[3];
-
- in[0] = mem;
- in[1] = frame;
- in[2] = data;
- irn = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
- a = init_node_attr(irn, 3);
- a->ent = ent;
- a->offset = 0;
- be_node_set_reg_class(irn, 1, cls_frame);
- be_node_set_reg_class(irn, 2, cls_data);
- return irn;
-}
-
ir_node *be_new_FrameAddr(const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, ir_entity *ent)
{
be_frame_attr_t *a;
return optimize_node(irn);
}
-ir_node *be_get_FrameAddr_frame(ir_node *node) {
+ir_node *be_get_FrameAddr_frame(const ir_node *node) {
assert(be_is_FrameAddr(node));
return get_irn_n(node, be_pos_FrameAddr_ptr);
}
+ir_entity *be_get_FrameAddr_entity(const ir_node *node)
+{
+ const be_frame_attr_t *attr = get_irn_generic_attr_const(node);
+ return attr->ent;
+}
+
ir_node *be_new_CopyKeep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, int n, ir_node *in_keep[], ir_mode *mode)
{
ir_node *irn;
ir_node *be_new_CopyKeep_single(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, ir_node *keep, ir_mode *mode)
{
- ir_node *in[1];
-
- in[0] = keep;
- return be_new_CopyKeep(cls, irg, bl, src, 1, in, mode);
+ return be_new_CopyKeep(cls, irg, bl, src, 1, &keep, mode);
}
ir_node *be_get_CopyKeep_op(const ir_node *cpy) {
return proj;
}
+/* Construct a new be_Unwind. */
+ir_node *be_new_Unwind(dbg_info *dbg, ir_graph *irg, ir_node *block,
+ ir_node *mem, ir_node *sp)
+{
+ ir_node *res;
+ ir_node *in[2];
+
+ in[be_pos_Unwind_mem] = mem;
+ in[be_pos_Unwind_sp] = sp;
+ res = new_ir_node(dbg, irg, block, op_be_Unwind, mode_X, 2, in);
+ init_node_attr(res, -1);
+
+ return res;
+}
+
int be_is_Spill (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill ; }
int be_is_Reload (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Reload ; }
int be_is_Copy (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Copy ; }
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 ; }
-int be_is_StackParam (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_StackParam ; }
int be_is_FrameAddr (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr ; }
-int be_is_FrameLoad (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameLoad ; }
-int be_is_FrameStore (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameStore ; }
int be_is_Barrier (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier ; }
+int be_is_Unwind (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Unwind ; }
int be_has_frame_entity(const ir_node *irn)
{
- switch(be_get_irn_opcode(irn)) {
- case beo_StackParam:
+ switch (be_get_irn_opcode(irn)) {
case beo_Spill:
case beo_Reload:
- case beo_FrameStore:
- case beo_FrameLoad:
case beo_FrameAddr:
return 1;
default:
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);
set_irn_n(incsp, 0, pred);
}
-ir_node *be_get_IncSP_mem(ir_node *irn) {
- assert(be_is_IncSP(irn));
- return get_irn_n(irn, 1);
-}
-
void be_set_IncSP_offset(ir_node *irn, int offset)
{
- be_stack_attr_t *a = get_irn_attr(irn);
+ be_incsp_attr_t *a = get_irn_attr(irn);
assert(be_is_IncSP(irn));
a->offset = offset;
}
int be_get_IncSP_offset(const ir_node *irn)
{
- be_stack_attr_t *a = get_irn_attr(irn);
+ const be_incsp_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;
XXX(Perm, perm);
XXX(Copy, copy);
XXX(Return, branch);
- XXX(StackParam, stackparam);
#undef XXX
default:
return arch_irn_class_normal;
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;
}
/*
void be_phi_handler_free(arch_irn_handler_t *handler)
{
- phi_handler_t *h = (void *) handler;
+ phi_handler_t *h = get_phi_handler_from_handler(handler);
pmap_destroy(h->phi_attrs);
+ h->phi_attrs = NULL;
free(handler);
}
fprintf(f, get_op_name(get_irn_op(irn)));
break;
case dump_node_mode_txt:
- fprintf(f, get_mode_name(get_irn_mode(irn)));
+ if(be_is_Perm(irn) || be_is_Copy(irn) || be_is_CopyKeep(irn)) {
+ fprintf(f, " %s", get_mode_name(get_irn_mode(irn)));
+ }
break;
case dump_node_nodeattr_txt:
+ if(be_is_Call(irn)) {
+ be_call_attr_t *a = (be_call_attr_t *) at;
+ if (a->ent)
+ fprintf(f, " [%s] ", get_entity_name(a->ent));
+ }
+ if(be_is_IncSP(irn)) {
+ const be_incsp_attr_t *attr = get_irn_generic_attr_const(irn);
+ if(attr->offset == BE_STACK_FRAME_SIZE_EXPAND) {
+ fprintf(f, " [Setup Stackframe] ");
+ } else if(attr->offset == BE_STACK_FRAME_SIZE_SHRINK) {
+ fprintf(f, " [Destroy Stackframe] ");
+ } else {
+ fprintf(f, " [%d] ", attr->offset);
+ }
+ }
break;
case dump_node_info_txt:
dump_node_reqs(f, irn);
if(be_has_frame_entity(irn)) {
be_frame_attr_t *a = (be_frame_attr_t *) at;
if (a->ent) {
- int bits = get_type_size_bits(get_entity_type(a->ent));
- ir_fprintf(f, "frame entity: %+F, offset 0x%x (%d), size 0x%x (%d) bits\n",
- a->ent, a->offset, a->offset, bits, bits);
+ unsigned size = get_type_size_bytes(get_entity_type(a->ent));
+ ir_fprintf(f, "frame entity: %+F, offset 0x%x (%d), size 0x%x (%d) bytes\n",
+ a->ent, a->offset, a->offset, size, size);
}
}
switch(be_get_irn_opcode(irn)) {
case beo_IncSP:
{
- be_stack_attr_t *a = (be_stack_attr_t *) at;
+ be_incsp_attr_t *a = (be_incsp_attr_t *) at;
if (a->offset == BE_STACK_FRAME_SIZE_EXPAND)
fprintf(f, "offset: FRAME_SIZE\n");
else if(a->offset == BE_STACK_FRAME_SIZE_SHRINK)
*/
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;