Commit 60dc045e authored by Michael Beck's avatar Michael Beck
Browse files

made the stack layout accessible for the debug output

add array, and method parameter output for the stabs
parent b617ef11
......@@ -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);
......
......@@ -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;
}
/*
......
......@@ -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 */
......@@ -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
......@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment