Commit 656700e4 authored by Michael Beck's avatar Michael Beck
Browse files

- Allowing an initial stack_bias to be transmitted from the prolog generating function

- reverted 21738: old_bp is again part of the between type for ia32

[r21783]
parent b43a4e26
......@@ -496,11 +496,12 @@ static void TEMPLATE_abi_dont_save_regs(void *self, pset *s)
* Build the prolog, return the BASE POINTER register
*/
static const arch_register_t *TEMPLATE_abi_prologue(void *self, ir_node **mem,
pmap *reg_map)
pmap *reg_map, int *stack_bias)
{
TEMPLATE_abi_env_t *env = self;
(void) reg_map;
(void) mem;
(void) stack_bias;
if(env->flags.try_omit_fp)
return env->arch_env->sp;
......
......@@ -902,20 +902,19 @@ static void arm_abi_dont_save_regs(void *self, pset *s)
pset_insert_ptr(s, env->arch_env->bp);
}
/**
* Generate the routine prologue.
* Generate the routine prologue.
*
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param stack_bias Points to the current stack bias, can be modified if needed.
*
* @return The register which shall be used as a stack frame base.
*
* All nodes which define registers in @p reg_map must keep @p reg_map current.
*/
static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *reg_map) {
static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias) {
arm_abi_env_t *env = self;
ir_node *keep, *store;
ir_graph *irg;
......@@ -925,6 +924,8 @@ static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *
ir_node *fp, *ip, *lr, *pc;
ir_node *sp = be_abi_reg_map_get(reg_map, env->arch_env->sp);
(void) stack_bias;
if (env->flags.try_omit_fp)
return env->arch_env->sp;
......
......@@ -279,18 +279,16 @@ static int get_stack_entity_offset(be_stack_layout_t *frame, ir_entity *ent,
ir_type *t = get_entity_owner(ent);
int ofs = get_entity_offset(ent);
int i, index;
int index;
/* Find the type the entity is contained in. */
for(index = 0; index < N_FRAME_TYPES; ++index) {
if(frame->order[index] == t)
for (index = 0; index < N_FRAME_TYPES; ++index) {
if (frame->order[index] == t)
break;
/* Add the size of all the types below the one of the entity to the entity's offset */
ofs += get_type_size_bytes(frame->order[index]);
}
/* Add the size of all the types below the one of the entity to the entity's offset */
for(i = 0; i < index; ++i)
ofs += get_type_size_bytes(frame->order[i]);
/* correct the offset by the initial position of the frame pointer */
ofs -= frame->initial_offset;
......@@ -309,7 +307,7 @@ static ir_entity *search_ent_with_offset(ir_type *t, int offset)
for(i = 0, n = get_compound_n_members(t); i < n; ++i) {
ir_entity *ent = get_compound_member(t, i);
if(get_entity_offset(ent) == offset)
if (get_entity_offset(ent) == offset)
return ent;
}
......@@ -1865,7 +1863,7 @@ static void modify_irg(be_abi_irg_t *env)
mem = new_mem_proj;
/* Generate the Prologue */
fp_reg = call->cb->prologue(env->cb, &mem, env->regs);
fp_reg = call->cb->prologue(env->cb, &mem, env->regs, &env->frame->initial_bias);
/* do the stack allocation BEFORE the barrier, or spill code
might be added before it */
......@@ -2372,6 +2370,15 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env)
DEL_ARR_F(walker_env.sp_nodes);
}
/**
* Fix all stack accessing operations in the block bl.
*
* @param env the abi environment
* @param bl the block to process
* @param real_bias the bias value
*
* @return the bias at the end of this block
*/
static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int real_bias)
{
const arch_env_t *arch_env = env->birg->main_env->arch_env;
......@@ -2388,7 +2395,7 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int real_bias)
node.
*/
ir_entity *ent = arch_get_frame_entity(arch_env, irn);
if(ent) {
if (ent) {
int bias = omit_fp ? real_bias : 0;
int offset = get_stack_entity_offset(env->frame, ent, bias);
arch_set_frame_offset(arch_env, irn, offset);
......@@ -2402,13 +2409,13 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int real_bias)
*/
ofs = arch_get_sp_bias(arch_env, irn);
if(be_is_IncSP(irn)) {
if (be_is_IncSP(irn)) {
/* fill in real stack frame size */
if(ofs == BE_STACK_FRAME_SIZE_EXPAND) {
if (ofs == BE_STACK_FRAME_SIZE_EXPAND) {
ir_type *frame_type = get_irg_frame_type(env->birg->irg);
ofs = (int) get_type_size_bytes(frame_type);
be_set_IncSP_offset(irn, ofs);
} else if(ofs == BE_STACK_FRAME_SIZE_SHRINK) {
} else if (ofs == BE_STACK_FRAME_SIZE_SHRINK) {
ir_type *frame_type = get_irg_frame_type(env->birg->irg);
ofs = - (int)get_type_size_bytes(frame_type);
be_set_IncSP_offset(irn, ofs);
......@@ -2455,7 +2462,8 @@ struct bias_walk {
};
/**
* Block-Walker: fix all stack offsets
* Block-Walker: fix all stack offsets for all blocks
* except the start block
*/
static void stack_bias_walker(ir_node *bl, void *data)
{
......@@ -2467,17 +2475,19 @@ static void stack_bias_walker(ir_node *bl, void *data)
void be_abi_fix_stack_bias(be_abi_irg_t *env)
{
ir_graph *irg = env->birg->irg;
struct bias_walk bw;
be_stack_layout_t *frame = env->frame;
ir_graph *irg;
struct bias_walk bw;
stack_frame_compute_initial_offset(env->frame);
// stack_layout_dump(stdout, env->frame);
stack_frame_compute_initial_offset(frame);
// stack_layout_dump(stdout, frame);
/* Determine the stack bias at the end of the start block. */
bw.start_block_bias = process_stack_bias(env, get_irg_start_block(irg), 0);
bw.between_size = get_type_size_bytes(env->frame->between_type);
bw.start_block_bias = process_stack_bias(env, get_irg_start_block(irg), frame->initial_bias);
bw.between_size = get_type_size_bytes(frame->between_type);
/* fix the bias is all other blocks */
irg = env->birg->irg;
bw.env = env;
bw.start_block = get_irg_start_block(irg);
irg_block_walk_graph(irg, stack_bias_walker, NULL, &bw);
......
......@@ -84,14 +84,15 @@ struct _be_abi_callbacks_t {
/**
* Generate the prologue.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @return The register which shall be used as a stack frame base.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param stack_bias Points to the current stack bias, can be modified if needed.
* @return The register which shall be used as a stack frame base.
*
* All nodes which define registers in @p reg_map must keep @p reg_map current.
*/
const arch_register_t *(*prologue)(void *self, ir_node **mem, pmap *reg_map);
const arch_register_t *(*prologue)(void *self, ir_node **mem, pmap *reg_map, int *stack_bias);
/**
* Generate the epilogue.
......@@ -157,6 +158,11 @@ be_abi_call_flags_t be_abi_call_get_flags(const be_abi_call_t *call);
ir_type *be_abi_call_get_method_type(const be_abi_call_t *call);
be_abi_irg_t *be_abi_introduce(be_irg_t *bi);
/**
* Fix the stack bias for all nodes accessing the stack frame using the
* stack pointer.
*/
void be_abi_fix_stack_bias(be_abi_irg_t *env);
void be_abi_free(be_abi_irg_t *abi);
......@@ -189,7 +195,7 @@ ir_node *be_abi_get_ignore_irn(be_abi_irg_t *abi, const arch_register_t *reg);
* - between_type: A struct type describing the stack layout between arguments
* and frame type. In architectures that put the return address
* automatically on the stack, the return address is put here.
* - frame_type: A class type describing the frame layout
* - 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. */
......@@ -198,9 +204,10 @@ struct _be_stack_layout_t {
ir_type *order[N_FRAME_TYPES]; /**< arg, between and frame types ordered. */
int initial_offset;
int stack_dir; /**< -1 for decreasing, 1 for increasing. */
ir_entity **param_map; /**< An array mapping type parameters to arg_type entries */
int initial_offset; /**< the initial difference between stack pointer and frame pointer */
int initial_bias; /**< the initial stack bias */
int stack_dir; /**< -1 for decreasing, 1 for increasing. */
};
/**
......
......@@ -410,15 +410,16 @@ static void ia32_abi_dont_save_regs(void *self, pset *s)
/**
* Generate the routine prologue.
*
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param stack_bias Points to the current stack bias, can be modified if needed.
*
* @return The register which shall be used as a stack frame base.
* @return The register which shall be used as a stack frame base.
*
* All nodes which define registers in @p reg_map must keep @p reg_map current.
*/
static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
{
ia32_abi_env_t *env = self;
ia32_code_gen_t *cg = ia32_current_cg;
......@@ -444,6 +445,9 @@ static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap
arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
set_ia32_flags(push, arch_irn_flags_ignore);
/* this modifies the stack bias, because we pushed 32bit */
*stack_bias -= 4;
/* move esp to ebp */
curr_bp = be_new_Copy(arch_env->bp->reg_class, irg, bl, curr_sp);
be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), arch_env->bp);
......@@ -558,23 +562,37 @@ static void ia32_abi_done(void *self) {
static ir_type *ia32_abi_get_between_type(void *self)
{
#define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
static ir_type *between_type = NULL;
(void) self;
static ir_type *omit_fp_between_type = NULL;
static ir_type *between_type = NULL;
ia32_abi_env_t *env = self;
if (! between_type) {
ir_entity *old_bp_ent;
ir_entity *ret_addr_ent;
ir_type *ret_addr_type;
ir_entity *omit_fp_ret_addr_ent;
ir_type *old_bp_type = new_type_primitive(IDENT("bp"), mode_Iu);
ir_type *ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_Iu);
ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_Iu);
between_type = new_type_struct(IDENT("ia32_between_type"));
ret_addr_ent = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
between_type = new_type_struct(IDENT("ia32_between_type"));
old_bp_ent = new_entity(between_type, IDENT("old_bp"), old_bp_type);
ret_addr_ent = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
set_entity_offset(ret_addr_ent, 0);
set_type_size_bytes(between_type, get_type_size_bytes(ret_addr_type));
set_entity_offset(old_bp_ent, 0);
set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
set_type_state(between_type, layout_fixed);
omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);
set_entity_offset(omit_fp_ret_addr_ent, 0);
set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
set_type_state(omit_fp_between_type, layout_fixed);
}
return between_type;
return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
#undef IDENT
}
......
......@@ -692,7 +692,7 @@ static void mips_abi_dont_save_regs(void *self, pset *s)
pset_insert_ptr(s, env->arch_env->bp);
}
static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap *reg_map)
static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap *reg_map, int *stack_bias)
{
mips_abi_env_t *env = self;
ir_graph *irg = env->irg;
......@@ -701,7 +701,9 @@ static const arch_register_t *mips_abi_prologue(void *self, ir_node** mem, pmap
ir_node *fp = be_abi_reg_map_get(reg_map, &mips_gp_regs[REG_FP]);
int initialstackframesize;
if(env->debug) {
(void) stack_bias;
if (env->debug) {
/*
* The calling conventions wants a stack frame of at least 24bytes size with
* a0-a3 saved in offset 0-12
......
......@@ -322,22 +322,25 @@ static void ppc32_abi_regs_saved_by_me(void *self, pset *regs)
/**
* Generate the prologue.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A mapping mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param self The callback object.
* @param mem A pointer to the mem node. Update this if you define new memory.
* @param reg_map A mapping mapping all callee_save/ignore/parameter registers to their defining nodes.
* @param stack_bias Points to the current stack bias, can be modified if needed.
*
* @return The register which shall be used as a stack frame base.
*
* All nodes which define registers in @p reg_map must keep @p reg_map current.
*/
static const arch_register_t *ppc32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
static const arch_register_t *ppc32_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
{
ppc32_abi_env *env = (ppc32_abi_env *) self;
be_abi_call_flags_t flags = be_abi_call_get_flags(env->call);
(void) mem;
(void) reg_map;
(void) stack_bias;
isleaf = flags.bits.irg_is_leaf;
if(flags.bits.try_omit_fp)
if (flags.bits.try_omit_fp)
return &ppc32_gp_regs[REG_R1];
else
return &ppc32_gp_regs[REG_R31];
......
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