* @cvsid $Id$
*/
#include "obst.h"
+#include "beabi_t.h"
typedef struct dbg_handle dbg_handle;
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);
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);
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. */
* @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;
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;
* @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;
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 */
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);
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;
/**
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;)
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, ¶m_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) {
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;
+}
/*
#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 */
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
#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 {
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 */
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
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 */
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 */
/**
* 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;
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 */
} /* 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 */