added new nodes for intrinsic lowering
[libfirm] / ir / be / benode.c
index 70cd604..99ffc6d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Backend node support.
  *
- * This file provdies Perm, Copy, Spill and Reload nodes.
+ * This file provides Perm, Copy, Spill and Reload nodes.
  *
  * Copyright (C) 2005 Universitaet Karlsruhe
  * Released under the GPL
@@ -84,28 +84,40 @@ typedef struct {
        be_req_t              in_req;
 } be_reg_data_t;
 
+/** The generic be nodes attribute type. */
 typedef struct {
-       int                         max_reg_data;
-       be_reg_data_t               *reg_data;
+       int                   max_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;
+       int            num_ret_vals;  /**< number of return values */
+} be_return_attr_t;
+
+/** The be_Stack attribute type. */
 typedef struct {
        be_node_attr_t node_attr;
        int offset;           /**< The offset by which the stack shall be increased/decreased. */
-       be_stack_dir_t dir;   /**< The direction in which the stack shall be modified (along or in the other direction). */
+       be_stack_dir_t dir;   /**< The direction in which the stack shall be modified (expand or shrink). */
 } be_stack_attr_t;
 
+/** The be_Frame attribute type. */
 typedef struct {
        be_node_attr_t node_attr;
        entity *ent;
        int offset;
 } be_frame_attr_t;
 
+/** The be_Call attribute type. */
 typedef struct {
        be_node_attr_t node_attr;
-       entity *ent;
+       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_call_attr_t;
 
+/** The be_Spill attribute type. */
 typedef struct {
        be_frame_attr_t frame_attr;
        ir_node *spill_ctx;  /**< The node in whose context this spill was introduced. */
@@ -143,6 +155,8 @@ static const ir_op_ops be_node_op_ops;
 #define H   irop_flag_highlevel
 #define c   irop_flag_constlike
 #define K   irop_flag_keep
+#define M   irop_flag_machine
+
 
 void be_node_init(void) {
        static int inited = 0;
@@ -155,23 +169,23 @@ void be_node_init(void) {
        /* Acquire all needed opcodes. */
        beo_base = get_next_ir_opcodes(beo_Last - 1);
 
-       op_be_Spill      = new_ir_op(beo_base + beo_Spill,      "Spill",      op_pin_state_mem_pinned, N, oparity_unary,    0, sizeof(be_spill_attr_t), &be_node_op_ops);
-       op_be_Reload     = new_ir_op(beo_base + beo_Reload,     "Reload",     op_pin_state_mem_pinned, N, oparity_zero,     0, sizeof(be_frame_attr_t), &be_node_op_ops);
-       op_be_Perm       = new_ir_op(beo_base + beo_Perm,       "Perm",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_node_attr_t),  &be_node_op_ops);
-       op_be_Copy       = new_ir_op(beo_base + beo_Copy,       "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,       "Keep",       op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),  &be_node_op_ops);
-       op_be_CopyKeep   = new_ir_op(beo_base + beo_CopyKeep,   "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,       "Call",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_call_attr_t),  &be_node_op_ops);
-       op_be_Return     = new_ir_op(beo_base + beo_Return,     "Return",     op_pin_state_pinned,     X, oparity_variable, 0, sizeof(be_node_attr_t),  &be_node_op_ops);
-       op_be_AddSP      = new_ir_op(beo_base + beo_AddSP,      "AddSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_node_attr_t),  &be_node_op_ops);
-       op_be_SetSP      = new_ir_op(beo_base + beo_SetSP,      "SetSP",      op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_stack_attr_t), &be_node_op_ops);
-       op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "IncSP",      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,  "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, "StackParam", op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t), &be_node_op_ops);
-       op_be_FrameAddr  = new_ir_op(beo_base + beo_FrameAddr,  "FrameAddr",  op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_frame_attr_t), &be_node_op_ops);
-       op_be_FrameLoad  = new_ir_op(beo_base + beo_FrameLoad,  "FrameLoad",  op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t), &be_node_op_ops);
-       op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "FrameStore", op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t), &be_node_op_ops);
-       op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "Barrier",    op_pin_state_pinned,     N, oparity_any,      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_mem_pinned, N, oparity_unary,    0, sizeof(be_spill_attr_t),  &be_node_op_ops);
+       op_be_Reload     = new_ir_op(beo_base + beo_Reload,     "be_Reload",     op_pin_state_mem_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_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_variable, 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,     N, 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_variable, 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_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_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      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_pinned,     N, oparity_unary,    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_pinned,     N, oparity_binary,   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_pinned,     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_pinned,     N, oparity_any,      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_any,      0, sizeof(be_node_attr_t),   &be_node_op_ops);
 
        set_op_tag(op_be_Spill,      &be_node_tag);
        set_op_tag(op_be_Reload,     &be_node_tag);
@@ -189,9 +203,12 @@ void be_node_init(void) {
        set_op_tag(op_be_FrameLoad,  &be_node_tag);
        set_op_tag(op_be_FrameStore, &be_node_tag);
        set_op_tag(op_be_FrameAddr,  &be_node_tag);
-       set_op_tag(op_be_Barrier,   &be_node_tag);
+       set_op_tag(op_be_Barrier,    &be_node_tag);
 }
 
+/**
+ * Initializes the generic attribute of all be nodes and return ir.
+ */
 static void *init_node_attr(ir_node* irn, int max_reg_data)
 {
        ir_graph *irg     = get_irn_irg(irn);
@@ -324,6 +341,10 @@ ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *b
        return res;
 }
 
+ir_node *be_get_Copy_op(const ir_node *cpy) {
+       return get_irn_n(cpy, be_pos_Copy_op);
+}
+
 ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
 {
        int i;
@@ -338,51 +359,79 @@ ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *b
        return irn;
 }
 
-ir_node *be_new_Call(ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr, int n_outs, int n, ir_node *in[])
+ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr,
+                     int n_outs, int n, ir_node *in[], ir_type *call_tp)
 {
-       int real_n = 3 + n;
+       be_call_attr_t *a;
+       int real_n = be_pos_Call_first_arg + n;
        ir_node *irn;
        ir_node **real_in;
 
-       real_in = malloc(sizeof(real_in[0]) * (real_n));
-
-       real_in[0] = mem;
-       real_in[1] = sp;
-       real_in[2] = ptr;
-       memcpy(&real_in[3], in, n * sizeof(in[0]));
+       NEW_ARR_A(ir_node *, real_in, real_n);
+       real_in[be_pos_Call_mem] = mem;
+       real_in[be_pos_Call_sp]  = sp;
+       real_in[be_pos_Call_ptr] = ptr;
+       memcpy(&real_in[be_pos_Call_first_arg], in, n * sizeof(in[0]));
 
        irn = new_ir_node(NULL, irg, bl, op_be_Call, mode_T, real_n, real_in);
-       init_node_attr(irn, (n_outs > real_n ? n_outs : real_n));
+       a = init_node_attr(irn, (n_outs > real_n ? n_outs : real_n));
+       a->ent     = NULL;
+       a->call_tp = call_tp;
        return irn;
 }
 
-entity *be_Call_get_entity(const ir_node *call)
-{
+/* Gets the call entity or NULL if this is no static call. */
+entity *be_Call_get_entity(const ir_node *call) {
        be_call_attr_t *a = get_irn_attr(call);
        assert(be_is_Call(call));
        return a->ent;
 }
 
-void    be_Call_set_entity(ir_node *call, entity *ent)
-{
+/* Sets the call entity. */
+void be_Call_set_entity(ir_node *call, entity *ent) {
        be_call_attr_t *a = get_irn_attr(call);
        assert(be_is_Call(call));
        a->ent = ent;
 }
 
-ir_node *be_new_Return(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
+/* Gets the call type. */
+ir_type *be_Call_get_type(ir_node *call) {
+       be_call_attr_t *a = get_irn_attr(call);
+       assert(be_is_Call(call));
+       return a->call_tp;
+}
+
+/* Sets the call type. */
+void be_Call_set_type(ir_node *call, ir_type *call_tp) {
+       be_call_attr_t *a = get_irn_attr(call);
+       assert(be_is_Call(call));
+       a->call_tp = call_tp;
+}
+
+/* Construct a new be_Return. */
+ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *bl, int n_res, int n, ir_node *in[])
 {
-       ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Return, mode_X, n, in);
+       be_return_attr_t *a;
+       ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
        init_node_attr(irn, n);
+       a = get_irn_attr(irn);
+       a->num_ret_vals = n_res;
 
        return irn;
 }
 
+/* Returns the number of real returns values */
+int be_Return_get_n_rets(ir_node *ret)
+{
+       be_return_attr_t *a = get_irn_attr(ret);
+       return a->num_ret_vals;
+}
+
 ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, unsigned offset, be_stack_dir_t dir)
 {
        be_stack_attr_t *a;
        ir_node *irn;
-       ir_node *in[1];
+       ir_node *in[2];
 
        in[0]     = old_sp;
        in[1]     = mem;
@@ -391,7 +440,7 @@ ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
        a->dir    = dir;
        a->offset = offset;
 
-       be_node_set_flags(irn, -1, arch_irn_flags_ignore);
+       be_node_set_flags(irn, -1, arch_irn_flags_ignore | arch_irn_flags_modify_sp);
 
        /* Set output constraint to stack register. */
        be_node_set_reg_class(irn, 0, sp->reg_class);
@@ -413,7 +462,7 @@ ir_node *be_new_AddSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
        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);
+       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);
@@ -433,7 +482,7 @@ ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
        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);
+       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);
@@ -531,7 +580,7 @@ ir_node *be_new_CopyKeep(const arch_register_class_t *cls, ir_graph *irg, ir_nod
        in[0] = src;
        memcpy(&in[1], in_keep, n * sizeof(in[0]));
        irn   = new_ir_node(NULL, irg, bl, op_be_CopyKeep, mode, n + 1, in);
-       init_node_attr(irn, n);
+       init_node_attr(irn, n + 1);
        be_node_set_reg_class(irn, OUT_POS(0), cls);
        be_node_set_reg_class(irn, 0, cls);
 
@@ -558,6 +607,7 @@ ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
 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_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
 int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
 int be_is_Keep          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Keep           ; }
 int be_is_Call          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Call           ; }
@@ -582,9 +632,9 @@ int be_has_frame_entity(const ir_node *irn)
        case beo_FrameLoad:
        case beo_FrameAddr:
                return 1;
+       default:
+               return 0;
        }
-
-       return 0;
 }
 
 entity *be_get_frame_entity(const ir_node *irn)
@@ -676,6 +726,21 @@ void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type)
        r->req.type = type;
 }
 
+ir_node *be_get_IncSP_pred(ir_node *irn) {
+       assert(be_is_IncSP(irn));
+       return get_irn_n(irn, 0);
+}
+
+void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) {
+       assert(be_is_IncSP(incsp));
+       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, unsigned offset)
 {
        be_stack_attr_t *a = get_irn_attr(irn);
@@ -758,8 +823,6 @@ static INLINE ir_node *find_a_spill(const ir_node *irn)
 
 entity *be_get_spill_entity(const ir_node *irn)
 {
-       int opc           = get_irn_opcode(irn);
-
        switch(be_get_irn_opcode(irn)) {
        case beo_Reload:
                {
@@ -827,7 +890,7 @@ ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn, ir_node *ctx)
         */
 
        insert = sched_next(irn);
-       if(bl == get_irg_start_block(irg) && insert != bl && sched_get_time_step(frame) >= sched_get_time_step(insert))
+       if(insert != bl && bl == get_irg_start_block(irg) && sched_get_time_step(frame) >= sched_get_time_step(insert))
                insert = sched_next(frame);
 
        while((is_Phi(insert) || is_Proj(insert)) && !sched_is_end(insert))
@@ -881,7 +944,7 @@ static void *put_out_reg_req(arch_register_req_t *req, const ir_node *irn, int o
 
                if(be_is_Copy(irn)) {
                        req->type |= arch_register_req_type_should_be_same;
-                       req->other_same = get_irn_n(irn, be_pos_Copy_orig);
+                       req->other_same = be_get_Copy_op(irn);
                }
        }
        else {
@@ -895,7 +958,6 @@ static void *put_out_reg_req(arch_register_req_t *req, const ir_node *irn, int o
 static void *put_in_reg_req(arch_register_req_t *req, const ir_node *irn, int pos)
 {
        const be_node_attr_t *a = get_irn_attr(irn);
-       int n                   = get_irn_arity(irn);
 
        if(pos < get_irn_arity(irn) && pos < a->max_reg_data)
                memcpy(req, &a->reg_data[pos].in_req, sizeof(req[0]));
@@ -948,11 +1010,12 @@ static arch_irn_class_t be_node_classify(const void *_self, const ir_node *irn)
        redir_proj((const ir_node **) &irn, -1);
 
        switch(be_get_irn_opcode(irn)) {
-#define XXX(a,b) case beo_ ## a: return arch_irn_class_ ## b;
-               XXX(Spill, spill)
-               XXX(Reload, reload)
-               XXX(Perm, perm)
-               XXX(Copy, copy)
+#define XXX(a,b) case beo_ ## a: return arch_irn_class_ ## b
+               XXX(Spill, spill);
+               XXX(Reload, reload);
+               XXX(Perm, perm);
+               XXX(Copy, copy);
+               XXX(Return, branch);
 #undef XXX
                default:
                return 0;
@@ -1054,7 +1117,6 @@ static const arch_register_req_t *get_Phi_reg_req_recursive(const phi_handler_t
 {
        int n = get_irn_arity(phi);
        ir_node *op;
-       int done = 0;
        int i;
 
        if(*visited && pset_find_ptr(*visited, phi))
@@ -1184,6 +1246,9 @@ void be_phi_handler_reset(arch_irn_handler_t *handler)
                                                 |_|            |___/
 */
 
+/**
+ * Dumps a register requirement to a file.
+ */
 static void dump_node_req(FILE *f, int idx, be_req_t *req)
 {
        unsigned i;
@@ -1218,6 +1283,9 @@ static void dump_node_req(FILE *f, int idx, be_req_t *req)
                fprintf(f, "\n");
 }
 
+/**
+ * Dumps node register requirements to a file.
+ */
 static void dump_node_reqs(FILE *f, ir_node *irn)
 {
        int i;
@@ -1241,6 +1309,9 @@ static void dump_node_reqs(FILE *f, ir_node *irn)
        }
 }
 
+/**
+ * ir_op-Operation: dump a be node to file
+ */
 static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason)
 {
        be_node_attr_t *at = get_irn_attr(irn);
@@ -1261,8 +1332,11 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason)
 
                        if(be_has_frame_entity(irn)) {
                                be_frame_attr_t *a = (be_frame_attr_t *) at;
-                               if (a->ent)
-                                       ir_fprintf(f, "frame entity: %+F offset %x (%d)\n", a->ent, a->offset, a->offset);
+                               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\n",
+                                         a->ent, a->offset, a->offset, bits, bits);
+                               }
 
                        }
 
@@ -1277,18 +1351,30 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason)
                        case beo_IncSP:
                                {
                                        be_stack_attr_t *a = (be_stack_attr_t *) at;
-                                       fprintf(f, "offset: %u\n", a->offset);
-                                       fprintf(f, "direction: %s\n", a->dir == be_stack_dir_along ? "along" : "against");
+                                       if (a->offset == BE_STACK_FRAME_SIZE)
+                                               fprintf(f, "offset: FRAME_SIZE\n");
+                                       else
+                                               fprintf(f, "offset: %u\n", a->offset);
+                                       fprintf(f, "direction: %s\n", a->dir == be_stack_dir_expand ? "expand" : "shrink");
                                }
                                break;
-                       }
+                       case beo_Call:
+                               {
+                                       be_call_attr_t *a = (be_call_attr_t *) at;
 
+                                       if (a->ent)
+                                               fprintf(f, "\ncalling: %s\n", get_entity_name(a->ent));
+                               }
+                       default:
+                               break;
+                       }
        }
 
        return 0;
 }
 
 /**
+ * ir_op-Operation:
  * Copies the backend specific attributes from old node to new node.
  */
 static void copy_attr(const ir_node *old_node, ir_node *new_node)