made the stack layout accessible for the debug output
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 12 Sep 2006 15:50:55 +0000 (15:50 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 12 Sep 2006 15:50:55 +0000 (15:50 +0000)
add array, and method parameter output for the stabs

ir/be/be_dbgout.h
ir/be/beabi.c
ir/be/beabi.h
ir/be/beabi_t.h
ir/be/bestabs.c

index 82f948b..c2c179d 100644 (file)
@@ -8,6 +8,7 @@
  * @cvsid  $Id$
  */
 #include "obst.h"
+#include "beabi_t.h"
 
 typedef struct dbg_handle dbg_handle;
 
@@ -25,7 +26,7 @@ typedef struct debug_ops {
        void (*main_program)(dbg_handle *handle);
 
        /** dumps the stabs for a function */
-       void (*method)(dbg_handle *handle, entity *ent);
+       void (*method)(dbg_handle *handle, entity *ent, const be_stack_layout_t *layout);
 
        /** dumps a line number */
        void (*line)(dbg_handle *handle, unsigned lineno, const char *address);
@@ -53,7 +54,7 @@ void be_dbg_so(dbg_handle *handle, const char *filename);
 void be_dbg_main_program(dbg_handle *handle);
 
 /** debug for a function */
-void be_dbg_method(dbg_handle *handle, entity *ent);
+void be_dbg_method(dbg_handle *handle, entity *ent, const be_stack_layout_t *layout);
 
 /** debug for line number */
 void be_dbg_line(dbg_handle *handle, unsigned lineno, const char *address);
index ce33286..bc29eee 100644 (file)
@@ -56,27 +56,6 @@ struct _be_abi_call_t {
        set *params;
 };
 
-#define N_FRAME_TYPES 3
-
-/**
- * This type describes the stack layout.
- * The stack is divided into 3 parts:
- * - arg_type:     A struct type describing the stack arguments and it's order.
- * - between_type: A struct type describing the stack layout between arguments
- *                 and frame type
- * - frame_type:   A class type descibing the frame layout
- */
-typedef struct _be_stack_layout_t {
-       ir_type *arg_type;                 /**< A type describing the stack argument layout. */
-       ir_type *between_type;             /**< A type describing the "between" layout. */
-       ir_type *frame_type;               /**< The frame type. */
-
-       ir_type *order[N_FRAME_TYPES];     /**< arg, between and frame types ordered. */
-
-       int initial_offset;
-       int stack_dir;                     /**< -1 for decreasing, 1 for increasing. */
-} be_stack_layout_t;
-
 struct _be_abi_irg_t {
        struct obstack       obst;
        be_stack_layout_t    *frame;        /**< The stack frame model. */
@@ -314,11 +293,13 @@ static int stack_frame_compute_initial_offset(be_stack_layout_t *frame)
  * @param between   the between layout type
  * @param locals    the method frame type
  * @param stack_dir the stack direction
+ * @param param_map an array mapping method argument positions to the stack argument type
  *
  * @return the initialized stack layout
  */
 static be_stack_layout_t *stack_frame_init(be_stack_layout_t *frame, ir_type *args,
-                                           ir_type *between, ir_type *locals, int stack_dir)
+                                           ir_type *between, ir_type *locals, int stack_dir,
+                                           entity *param_map[])
 {
        frame->arg_type       = args;
        frame->between_type   = between;
@@ -326,6 +307,7 @@ static be_stack_layout_t *stack_frame_init(be_stack_layout_t *frame, ir_type *ar
        frame->initial_offset = 0;
        frame->stack_dir      = stack_dir;
        frame->order[1]       = between;
+       frame->param_map      = param_map;
 
        if(stack_dir > 0) {
                frame->order[0] = args;
@@ -1095,10 +1077,11 @@ static void clearup_frame(be_abi_irg_t *env, ir_node *ret, pmap *reg_map, struct
  * @param env          the ABI environment
  * @param call         the current call ABI
  * @param method_type  the method type
+ * @param param_map    an array mapping method arguments to the stack layout type
  *
  * @return the stack argument layout type
  */
-static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type *method_type)
+static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type *method_type, entity ***param_map)
 {
        int dir  = env->call->flags.bits.left_to_right ? 1 : -1;
        int inc  = env->birg->main_env->arch_env->isa->stack_dir * dir;
@@ -1111,12 +1094,15 @@ static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type
        int i;
        ir_type *val_param_tp = get_method_value_param_type(method_type);
        ident *id = get_entity_ident(get_irg_entity(env->birg->irg));
+       entity **map;
 
+       *param_map = map = obstack_alloc(&env->obst, n * sizeof(entity *));
        res = new_type_struct(mangle_u(id, new_id_from_chars("arg_type", 8)));
        for (i = 0; i < n; ++i, curr += inc) {
                ir_type *param_type    = get_method_param_type(method_type, curr);
                be_abi_call_arg_t *arg = get_call_arg(call, 0, curr);
 
+               map[i] = NULL;
                if (arg->on_stack) {
                        if (val_param_tp) {
                                /* the entity was already created, move it to the param type */
@@ -1136,6 +1122,7 @@ static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type
                        set_entity_offset_bytes(arg->stack_ent, ofs);
                        ofs += arg->space_after;
                        ofs += get_type_size_bytes(param_type);
+                       map[i] = arg->stack_ent;
                }
        }
        set_type_size_bytes(res, ofs);
@@ -1392,7 +1379,7 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i
 
 typedef struct lower_frame_sels_env_t {
        be_abi_irg_t *env;
-       entity       *value_param_list;  /**< the list of all value param antities */
+       entity       *value_param_list;  /**< the list of all value param entities */
 } lower_frame_sels_env_t;
 
 /**
@@ -1561,6 +1548,7 @@ static void modify_irg(be_abi_irg_t *env)
        const ir_edge_t *edge;
        ir_type *arg_type, *bet_type;
        lower_frame_sels_env_t ctx;
+       entity **param_map;
 
        bitset_t *used_proj_nr;
        DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
@@ -1601,9 +1589,9 @@ static void modify_irg(be_abi_irg_t *env)
                DBG((dbg, LEVEL_2, "\treading arg: %d -> %+F\n", nr, irn));
        }
 
-       arg_type = compute_arg_type(env, call, method_type);
+       arg_type = compute_arg_type(env, call, method_type, &param_map);
        bet_type = call->cb->get_between_type(env->cb);
-       stack_frame_init(env->frame, arg_type, bet_type, get_irg_frame_type(irg), isa->stack_dir);
+       stack_frame_init(env->frame, arg_type, bet_type, get_irg_frame_type(irg), isa->stack_dir, param_map);
 
        /* Count the register params and add them to the number of Projs for the RegParams node */
        for(i = 0; i < n_params; ++i) {
@@ -1834,6 +1822,10 @@ void be_abi_put_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls,
                        bitset_set(bs, reg->index);
 }
 
+/* Returns the stack layout from a abi environment. */
+const be_stack_layout_t *be_abi_get_stack_layout(const be_abi_irg_t *abi) {
+       return abi->frame;
+}
 
 /*
 
index 7aa4dfc..e364bed 100644 (file)
@@ -128,4 +128,31 @@ ir_node *be_abi_get_callee_save_irn(be_abi_irg_t *abi, const arch_register_t *re
 #define be_abi_reg_map_get(map, reg)      pmap_get((map), (void *) (reg))
 #define be_abi_reg_map_set(map, reg, irn)  pmap_insert((map), (void *) (reg), (irn))
 
+#define N_FRAME_TYPES 3
+
+/**
+ * This type describes the stack layout.
+ * The stack is divided into 3 parts:
+ * - arg_type:     A struct type describing the stack arguments and it's order.
+ * - between_type: A struct type describing the stack layout between arguments
+ *                 and frame type
+ * - frame_type:   A class type describing the frame layout
+ */
+struct _be_stack_layout_t {
+       ir_type *arg_type;                 /**< A type describing the stack argument layout. */
+       ir_type *between_type;             /**< A type describing the "between" layout. */
+       ir_type *frame_type;               /**< The frame type. */
+
+       ir_type *order[N_FRAME_TYPES];     /**< arg, between and frame types ordered. */
+
+       int initial_offset;
+       int stack_dir;                     /**< -1 for decreasing, 1 for increasing. */
+       entity **param_map;                /**< An array mapping type parameters to arg_type entries */
+};
+
+/**
+ * Returns the stack layout from a abi environment.
+ */
+const be_stack_layout_t *be_abi_get_stack_layout(const be_abi_irg_t *abi);
+
 #endif /* _BEABI_H */
index 9acdd68..c17f095 100644 (file)
@@ -11,5 +11,6 @@ typedef union  _be_abi_call_flags_t      be_abi_call_flags_t;
 typedef struct _be_abi_callbacks_t       be_abi_callbacks_t;
 typedef struct _be_abi_call_t            be_abi_call_t;
 typedef struct _be_abi_irg_t             be_abi_irg_t;
+typedef struct _be_stack_layout_t        be_stack_layout_t;
 
 #endif
index 686129e..f66d1bc 100644 (file)
@@ -24,7 +24,9 @@
 #include "pdeq.h"
 #include "irtools.h"
 #include "obst.h"
+#include "array.h"
 #include "be_dbgout.h"
+#include "beabi.h"
 
 /* Non-Stab Symbol and Stab Symbol Types */
 enum stabs_types {
@@ -228,7 +230,7 @@ static void gen_pointer_type(stabs_handle *h, ir_type *tp) {
        unsigned type_num = assign_type_number(h, tp);
        unsigned el_num   = get_type_number(h, get_pointer_points_to_type(tp));
 
-       fprintf(h->f, "\t.stabs \"%s:T%u=*%u\",%d,0,0,0\n",
+       fprintf(h->f, "\t.stabs \"%s:t%u=*%u\",%d,0,0,0\n",
                get_type_name(tp), type_num, el_num, N_LSYM);
 }  /* gen_pointer_type */
 
@@ -290,6 +292,57 @@ static void gen_struct_union_type(stabs_handle *h, ir_type *tp) {
        fprintf(h->f, ";\",%d,0,0,0\n", N_LSYM);
 }  /* gen_struct_type */
 
+/**
+ * Generates an array type
+ *
+ * @param h    the stabs handle
+ * @param tp   the type
+ */
+static void gen_array_type(stabs_handle *h, ir_type *tp) {
+       unsigned type_num = assign_type_number(h, tp);
+       int i, n = get_array_n_dimensions(tp);
+       int *perm;
+       ir_type *etp;
+
+       NEW_ARR_A(int, perm, n);
+       for (i = 0; i < n; ++i) {
+               perm[i] = get_array_order(tp, i);
+       }
+       fprintf(h->f, "\t.stabs \"%s:t%u=a", get_type_name(tp), type_num);
+
+       for (i = 0; i < n; ++i) {
+               int dim = perm[i];
+               long min = get_array_lower_bound_int(tp, dim);
+               long max = get_array_upper_bound_int(tp, dim);
+
+               /* FIXME r1 must be integer type, but seems to work for now */
+               fprintf(h->f, "r1;%ld;%ld;", min, max-1);
+       }
+
+       etp = get_array_element_type(tp);
+       type_num = get_type_number(h, etp);
+       fprintf(h->f, "%d\",%d,0,0,0\n", type_num, N_LSYM);
+}  /* gen_array_type */
+
+/**
+ * Generates a method type
+ *
+ * @param h    the stabs handle
+ * @param tp   the type
+ */
+static void gen_method_type(stabs_handle *h, ir_type *tp) {
+       unsigned type_num = assign_type_number(h, tp);
+       ir_type *rtp = NULL;
+       unsigned res_type_num;
+
+       if (get_method_n_ress(tp) > 0)
+               rtp = get_method_res_type(tp, 0);
+       res_type_num = get_type_number(h, rtp);
+
+       fprintf(h->f, "\t.stabs \"%s:t%u=f%u\",%d,0,0,0\n",
+               get_type_name(tp), type_num, res_type_num, N_LSYM);
+}  /* gen_method_type */
+
 /**
  * type-walker: generate declaration for simple types,
  * put all other types on a wait queue
@@ -407,8 +460,7 @@ static void finish_types(stabs_handle *h, waitq *wq)
     case tpo_method:
       if (is_method_type_ready(tp)) {
         if (get_method_n_ress(tp) <= 1)
-          //gen_method_type(h, tp)
-                 ;
+          gen_method_type(h, tp);
         else {
           fprintf(stderr, "Warning: Cannot create stabs debug info for type %s\n", get_type_name(tp));
         }  /* if */
@@ -427,7 +479,7 @@ static void finish_types(stabs_handle *h, waitq *wq)
       break;
     case tpo_array:
       if (IS_TYPE_READY(get_array_element_type(tp))) {
-        //gen_array_type(h, tp);
+        gen_array_type(h, tp);
         SET_TYPE_READY(tp);
         continue;
       }  /* if */
@@ -494,11 +546,11 @@ static void stabs_line(dbg_handle *handle, unsigned lineno, const char *address)
 /**
  * dump the stabs for a function
  */
-static void stabs_method(dbg_handle *handle, entity *ent) {
+static void stabs_method(dbg_handle *handle, entity *ent, const be_stack_layout_t *layout) {
        stabs_handle *h = (stabs_handle *)handle;
        ir_type *mtp, *rtp;
        unsigned type_num;
-       int i, n;
+       int i, n, between_size;
 
        h->cur_ent = ent;
 
@@ -517,18 +569,25 @@ static void stabs_method(dbg_handle *handle, entity *ent) {
                N_FUN,
                get_entity_ld_name(ent));
 
+       between_size = get_type_size_bytes(layout->between_type);
        for (i = 0, n = get_method_n_params(mtp); i < n; ++i) {
                ir_type *ptp      = get_method_param_type(mtp, i);
         const char *name  = get_method_param_name(mtp, i);
                unsigned type_num = get_type_number(h, ptp);
         char buf[16];
         int ofs = 0;
+               entity *stack_ent;
 
         if (! name) {
           snprintf(buf, sizeof(buf), "arg%d", i);
           name = buf;
         }
-        /* FIXME: calculate the offset */
+               /* check if this parameter has a stack entity. If it has, it
+                  it transmitted on the stack, else in a register */
+               stack_ent = layout->param_map[i];
+               if (stack_ent) {
+                       ofs = get_entity_offset_bytes(stack_ent) + between_size;
+               }
                fprintf(h->f, "\t.stabs \"%s:p%u\",%d,0,0,%d\n", name, type_num, N_PSYM, ofs);
        }
 }  /* stabs_method */
@@ -616,9 +675,9 @@ void be_dbg_main_program(dbg_handle *h) {
 }  /* be_dbg_main_program */
 
 /** debug for a function */
-void be_dbg_method(dbg_handle *h, entity *ent) {
+void be_dbg_method(dbg_handle *h, entity *ent, const be_stack_layout_t *layout) {
        if (h->ops->method)
-               h->ops->method(h, ent);
+               h->ops->method(h, ent, layout);
 }  /* be_dbg_method */
 
 /** debug for line number */