From: Michael Beck Date: Wed, 20 Sep 2006 08:36:16 +0000 (+0000) Subject: When the Pop instruction is handled, only change the bias if the frame pointer X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=2794677a30b1d10eea32e51c30c4c6eebfc1333d;p=libfirm When the Pop instruction is handled, only change the bias if the frame pointer is omitted (and we use esp to address frame entities) --- diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index c83eb297e..efa4ee624 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -290,24 +290,16 @@ static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) { } } +/** + * The IA32 ABI callback object. + */ typedef struct { - be_abi_call_flags_bits_t flags; - const arch_isa_t *isa; - const arch_env_t *aenv; - ir_graph *irg; + be_abi_call_flags_bits_t flags; /**< The call flags. */ + const arch_isa_t *isa; /**< The ISA handle. */ + const arch_env_t *aenv; /**< The architecture environment. */ + ir_graph *irg; /**< The associated graph. */ } ia32_abi_env_t; -static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg) -{ - ia32_abi_env_t *env = xmalloc(sizeof(env[0])); - be_abi_call_flags_t fl = be_abi_call_get_flags(call); - env->flags = fl.bits; - env->irg = irg; - env->aenv = aenv; - env->isa = aenv->isa; - return env; -} - static entity *ia32_get_frame_entity(const void *self, const ir_node *irn) { return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL; } @@ -323,13 +315,14 @@ static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) { if (get_ia32_frame_ent(irn)) { ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn); - /* Pop nodes modify the stack pointer before calculating the destination - * address, so fix this here - */ if(is_ia32_Pop(irn)) { - ia32_abi_env_t *cb_env = get_abi_cb(ops->cg->birg->abi); - if (cb_env->flags.try_omit_fp) + int omit_fp = be_abi_omit_fp(ops->cg->birg->abi); + if (omit_fp) { + /* Pop nodes modify the stack pointer before calculating the destination + * address, so fix this here + */ bias -= 4; + } } DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias)); @@ -481,6 +474,32 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp); } +/** + * Initialize the callback object. + * @param call The call object. + * @param aenv The architecture environment. + * @param irg The graph with the method. + * @return Some pointer. This pointer is passed to all other callback functions as self object. + */ +static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg) +{ + ia32_abi_env_t *env = xmalloc(sizeof(env[0])); + be_abi_call_flags_t fl = be_abi_call_get_flags(call); + env->flags = fl.bits; + env->irg = irg; + env->aenv = aenv; + env->isa = aenv->isa; + return env; +} + +/** + * Destroy the callback object. + * @param self The callback object. + */ +static void ia32_abi_done(void *self) { + free(self); +} + /** * Produces the type which sits between the stack args and the locals on the stack. * it will contain the return address and space to store the old base pointer. @@ -757,7 +776,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node static const be_abi_callbacks_t ia32_abi_callbacks = { ia32_abi_init, - free, + ia32_abi_done, ia32_abi_get_between_type, ia32_abi_dont_save_regs, ia32_abi_prologue,