From 816e7e0779021990465292820aa997d2af768c72 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Wed, 9 Apr 2008 22:41:54 +0000 Subject: [PATCH] - add support for stack alignment on calls - fix pic trampolines not being generated twice [r19205] --- ir/be/TEMPLATE/bearch_TEMPLATE.c | 1 + ir/be/arm/bearch_arm.c | 3 +- ir/be/be_t.h | 3 + ir/be/beabi.c | 143 ++++++++++++++++++++----------- ir/be/bearch_t.h | 7 +- ir/be/bemain.c | 4 + ir/be/benode.c | 42 +++++---- ir/be/benode_t.h | 4 +- ir/be/ia32/bearch_ia32.c | 30 ++++--- ir/be/mips/bearch_mips.c | 1 + ir/be/ppc32/bearch_ppc32.c | 1 + 11 files changed, 154 insertions(+), 85 deletions(-) diff --git a/ir/be/TEMPLATE/bearch_TEMPLATE.c b/ir/be/TEMPLATE/bearch_TEMPLATE.c index 3ee2f7361..7aa0ace23 100644 --- a/ir/be/TEMPLATE/bearch_TEMPLATE.c +++ b/ir/be/TEMPLATE/bearch_TEMPLATE.c @@ -373,6 +373,7 @@ static TEMPLATE_isa_t TEMPLATE_isa_template = { &TEMPLATE_general_purpose_regs[REG_SP], /* stack pointer register */ &TEMPLATE_general_purpose_regs[REG_BP], /* base pointer register */ -1, /* stack direction */ + 1, /* stack alignment for calls */ NULL, /* main environment */ 7, /* costs for a spill instruction */ 5, /* costs for a reload instruction */ diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index e1e67cd9c..29b3de2ec 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -769,6 +769,7 @@ static arm_isa_t arm_isa_template = { &arm_gp_regs[REG_SP], /* stack pointer */ &arm_gp_regs[REG_R11], /* base pointer */ -1, /* stack direction */ + 1, /* stack alignment for calls */ NULL, /* main environment */ 7, /* spill costs */ 5, /* reload costs */ @@ -972,7 +973,7 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m // TODO: Activate Omit fp in epilogue if (env->flags.try_omit_fp) { - curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK); + curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0); add_irn_dep(curr_sp, *mem); curr_lr = be_new_CopyKeep_single(&arm_reg_classes[CLASS_arm_gp], env->irg, bl, curr_lr, curr_sp, get_irn_mode(curr_lr)); diff --git a/ir/be/be_t.h b/ir/be/be_t.h index cc08bcdb7..3c35d091e 100644 --- a/ir/be/be_t.h +++ b/ir/be/be_t.h @@ -31,6 +31,7 @@ #include "debug.h" #include "bitset.h" #include "timing.h" +#include "pmap.h" #include "be.h" #include "bearch.h" @@ -84,7 +85,9 @@ struct be_main_env_t { arch_code_generator_t *cg; arch_irn_handler_t *phi_handler; const char *cup_name; + pmap *ent_trampoline_map; ir_type *pic_trampolines_type; + pmap *ent_pic_symbol_map; ir_type *pic_symbols_type; }; diff --git a/ir/be/beabi.c b/ir/be/beabi.c index ac788c4a4..ab7732de4 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -108,7 +108,7 @@ struct _be_abi_irg_t { arch_register_req_t sp_req; arch_register_req_t sp_cls_req; - DEBUG_ONLY(firm_dbg_module_t *dbg;) /**< The debugging module. */ + DEBUG_ONLY(firm_dbg_module_t *dbg;) /**< The debugging module. */ }; static heights_t *ir_heights; @@ -271,7 +271,8 @@ static void be_abi_call_free(be_abi_call_t *call) and the spills. */ -static int get_stack_entity_offset(be_stack_layout_t *frame, ir_entity *ent, int bias) +static int get_stack_entity_offset(be_stack_layout_t *frame, ir_entity *ent, + int bias) { ir_type *t = get_entity_owner(ent); int ofs = get_entity_offset(ent); @@ -427,6 +428,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) struct obstack *obst = &env->obst; int no_alloc = call->flags.bits.frame_is_setup_on_call; int n_res = get_method_n_ress(call_tp); + int do_seq = call->flags.bits.store_args_sequential && !no_alloc; ir_node *res_proj = NULL; int n_reg_params = 0; @@ -473,10 +475,22 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) } reg_param_idxs = obstack_finish(obst); + /* + * If the stack is decreasing and we do not want to store sequentially, + * or someone else allocated the call frame + * we allocate as much space on the stack all parameters need, by + * moving the stack pointer along the stack's direction. + * + * Note: we also have to do this for stack_size == 0, because we may have + * to adjust stack alignment for the call. + */ + if (stack_dir < 0 && !do_seq && !no_alloc) { + curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, stack_size, 1); + } + /* If there are some parameters which shall be passed on the stack. */ if (n_stack_params > 0) { int curr_ofs = 0; - int do_seq = call->flags.bits.store_args_sequential && !no_alloc; /* * Reverse list of stack parameters if call arguments are from left to right. @@ -492,16 +506,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) } } - /* - * If the stack is decreasing and we do not want to store sequentially, - * or someone else allocated the call frame - * we allocate as much space on the stack all parameters need, by - * moving the stack pointer along the stack's direction. - */ - if (stack_dir < 0 && !do_seq && !no_alloc) { - curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, stack_size); - } - curr_mem = get_Call_mem(irn); if (! do_seq) { obstack_ptr_grow(obst, curr_mem); @@ -523,7 +527,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) */ if (do_seq) { curr_ofs = 0; - addr = curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, param_size + arg->space_before); + addr = curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, param_size + arg->space_before, 0); add_irn_dep(curr_sp, curr_mem); } else { @@ -805,11 +809,10 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) mem_proj = new_r_Proj(irg, bl, low_call, mode_M, pn_be_Call_M_regular); keep_alive(mem_proj); } - - /* Clean up the stack frame if we allocated it */ - if (! no_alloc) { - curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size); - } + } + /* Clean up the stack frame or revert alignment fixes if we allocated it */ + if (! no_alloc) { + curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size, 0); } be_abi_call_free(call); @@ -836,6 +839,7 @@ static ir_node *adjust_alloc_size(unsigned stack_alignment, ir_node *size, ir_graph *irg, ir_node *block, dbg_info *dbg) { if (stack_alignment > 1) { + assert(is_po2(stack_alignment)); ir_mode *mode = get_irn_mode(size); tarval *tv = new_tarval_from_long(stack_alignment-1, mode); ir_node *mask = new_r_Const(irg, block, mode, tv); @@ -918,9 +922,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp We cannot omit it. */ env->call->flags.bits.try_omit_fp = 0; - /* FIXME: size must be here round up for the stack alignment, but - this must be transmitted from the backend. */ - stack_alignment = 4; + stack_alignment = env->isa->stack_alignment; size = adjust_alloc_size(stack_alignment, size, irg, block, dbg); new_alloc = be_new_AddSP(env->isa->sp, irg, block, curr_sp, size); set_irn_dbg_info(new_alloc, dbg); @@ -989,10 +991,8 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) size = get_Free_size(free); } - /* FIXME: size must be here round up for the stack alignment, but - this must be transmitted from the backend. */ - stack_alignment = 4; - size = adjust_alloc_size(stack_alignment, size, irg, block, dbg); + stack_alignment = env->isa->stack_alignment; + size = adjust_alloc_size(stack_alignment, size, irg, block, dbg); /* The stack pointer will be modified in an unknown manner. We cannot omit it. */ @@ -1864,7 +1864,7 @@ static void modify_irg(be_abi_irg_t *env) /* do the stack allocation BEFORE the barrier, or spill code might be added before it */ env->init_sp = be_abi_reg_map_get(env->regs, sp); - env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, BE_STACK_FRAME_SIZE_EXPAND); + env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, BE_STACK_FRAME_SIZE_EXPAND, 0); be_abi_reg_map_set(env->regs, sp, env->init_sp); create_barrier(env, bl, &mem, env->regs, 0); @@ -2015,6 +2015,17 @@ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method) return ent; } +static ir_entity *get_trampoline(be_main_env_t *env, ir_entity *method) +{ + ir_entity *result = pmap_get(env->ent_trampoline_map, method); + if (result == NULL) { + result = create_trampoline(env, method); + pmap_insert(env->ent_trampoline_map, method, result); + } + + return result; +} + static int can_address_relative(ir_entity *entity) { return get_entity_variability(entity) == variability_initialized @@ -2058,7 +2069,7 @@ static void fix_pic_symconsts(ir_node *node, void *data) continue; dbgi = get_irn_dbg_info(pred); - trampoline = create_trampoline(be, entity); + trampoline = get_trampoline(be, entity); trampoline_const = new_rd_SymConst_addr_ent(dbgi, irg, mode_P_code, trampoline, NULL); set_irn_n(node, i, trampoline_const); continue; @@ -2286,11 +2297,12 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env) DEL_ARR_F(walker_env.sp_nodes); } -static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) +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; - int omit_fp = env->call->flags.bits.try_omit_fp; - ir_node *irn; + int omit_fp = env->call->flags.bits.try_omit_fp; + ir_node *irn; + int wanted_bias = real_bias; sched_foreach(bl, irn) { int ofs; @@ -2302,34 +2314,59 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) */ ir_entity *ent = arch_get_frame_entity(arch_env, irn); 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); - DBG((env->dbg, LEVEL_2, "%F has offset %d (including bias %d)\n", ent, offset, bias)); + DBG((env->dbg, LEVEL_2, "%F has offset %d (including bias %d)\n", + ent, offset, bias)); } - if(omit_fp || be_is_IncSP(irn)) { - /* - * If the node modifies the stack pointer by a constant offset, - * record that in the bias. - */ - ofs = arch_get_sp_bias(arch_env, irn); - - if(be_is_IncSP(irn)) { - if(ofs == BE_STACK_FRAME_SIZE_EXPAND) { - ofs = (int)get_type_size_bytes(get_irg_frame_type(env->birg->irg)); - be_set_IncSP_offset(irn, ofs); - } else if(ofs == BE_STACK_FRAME_SIZE_SHRINK) { - ofs = - (int)get_type_size_bytes(get_irg_frame_type(env->birg->irg)); - be_set_IncSP_offset(irn, ofs); + /* + * If the node modifies the stack pointer by a constant offset, + * record that in the bias. + */ + ofs = arch_get_sp_bias(arch_env, irn); + + if(be_is_IncSP(irn)) { + /* fill in real stack frame size */ + 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) { + 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 (be_get_IncSP_align(irn)) { + /* patch IncSP to produce an aligned stack pointer */ + ir_type *between_type = env->frame->between_type; + int between_size = get_type_size_bytes(between_type); + int alignment = env->isa->stack_alignment; + int delta = (real_bias + ofs + between_size) % env->isa->stack_alignment; + assert(ofs >= 0); + if (delta > 0) { + be_set_IncSP_offset(irn, ofs + alignment - delta); + real_bias += alignment - delta; + } + } else { + /* adjust so real_bias corresponds with wanted_bias */ + int delta = wanted_bias - real_bias; + assert(delta <= 0); + if(delta != 0) { + be_set_IncSP_offset(irn, ofs + delta); + real_bias += delta; + } } } - - if(omit_fp) - bias += ofs; } + + real_bias += ofs; + wanted_bias += ofs; } - return bias; + assert(real_bias == wanted_bias); + return real_bias; } /** @@ -2337,8 +2374,9 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) */ struct bias_walk { be_abi_irg_t *env; /**< The ABI irg environment. */ - int start_block_bias; /**< The bias at the end of the start block. */ - ir_node *start_block; /**< The start block of the current graph. */ + int start_block_bias; /**< The bias at the end of the start block. */ + int between_size; + ir_node *start_block; /**< The start block of the current graph. */ }; /** @@ -2362,6 +2400,7 @@ void be_abi_fix_stack_bias(be_abi_irg_t *env) /* 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); /* fix the bias is all other blocks */ bw.env = env; diff --git a/ir/be/bearch_t.h b/ir/be/bearch_t.h index 70914ac5a..4b10f6a2f 100644 --- a/ir/be/bearch_t.h +++ b/ir/be/bearch_t.h @@ -409,10 +409,11 @@ struct arch_isa_t { const arch_isa_if_t *impl; const arch_register_t *sp; /** The stack pointer register. */ const arch_register_t *bp; /** The base pointer register. */ - const int stack_dir; /** -1 for decreasing, 1 for increasing. */ + int stack_dir; /** -1 for decreasing, 1 for increasing. */ + int stack_alignment; /** stack alignment */ const be_main_env_t *main_env; /** the be main environment */ - const int spill_cost; /** cost for a be_Spill node */ - const int reload_cost; /** cost for a be_Reload node */ + int spill_cost; /** cost for a be_Spill node */ + int reload_cost; /** cost for a be_Reload node */ }; #define arch_isa_stack_dir(isa) ((isa)->stack_dir) diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 894bebe19..1498c6e2d 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -251,8 +251,10 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle) obstack_init(&env->obst); env->arch_env = obstack_alloc(&env->obst, sizeof(env->arch_env[0])); env->options = &be_options; + env->ent_trampoline_map = pmap_create(); env->pic_trampolines_type = new_type_class(new_id_from_str("$PIC_TRAMPOLINE_TYPE")); + env->ent_pic_symbol_map = pmap_create(); env->pic_symbols_type = new_type_struct(new_id_from_str("$PIC_SYMBOLS_TYPE")); @@ -286,6 +288,8 @@ static void be_done_env(be_main_env_t *env) be_phi_handler_free(env->phi_handler); obstack_free(&env->obst, NULL); + pmap_destroy(env->ent_trampoline_map); + pmap_destroy(env->ent_pic_symbol_map); free_type(env->pic_trampolines_type); free_type(env->pic_symbols_type); } diff --git a/ir/be/benode.c b/ir/be/benode.c index 06f44d8e1..fe56913bc 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -73,8 +73,8 @@ typedef struct { typedef struct { const arch_register_t *reg; - be_req_t req; - be_req_t in_req; + be_req_t req; + be_req_t in_req; } be_reg_data_t; /** The generic be nodes attribute type. */ @@ -92,28 +92,30 @@ typedef struct { /** The be_IncSP attribute type. */ typedef struct { be_node_attr_t node_attr; /**< base attributes of every be node. */ - int offset; /**< The offset by which the stack shall be expanded/shrinked. */ + int offset; /**< The offset by which the stack shall be expanded/shrinked. */ + int align; /**< wether stack should be aligned after the + IncSP */ } be_incsp_attr_t; /** The be_Frame attribute type. */ typedef struct { - be_node_attr_t node_attr; /**< base attributes of every be node. */ - ir_entity *ent; - int offset; + be_node_attr_t node_attr; /**< base attributes of every be node. */ + ir_entity *ent; + int offset; } be_frame_attr_t; /** The be_Call attribute type. */ typedef struct { - be_node_attr_t node_attr; /**< base attributes of every be node. */ - ir_entity *ent; /**< The called entity if this is a static call. */ - unsigned pop; - ir_type *call_tp; /**< The call type, copied from the original Call node. */ + be_node_attr_t node_attr; /**< base attributes of every be node. */ + ir_entity *ent; /**< The called entity if this is a static call. */ + unsigned pop; + ir_type *call_tp; /**< The call type, copied from the original Call node. */ } be_call_attr_t; typedef struct { - be_node_attr_t node_attr; /**< base attributes of every be node. */ - ir_entity **in_entities; - ir_entity **out_entities; + be_node_attr_t node_attr; /**< base attributes of every be node. */ + ir_entity **in_entities; + ir_entity **out_entities; } be_memperm_attr_t; ir_op *op_be_Spill; @@ -722,16 +724,19 @@ int be_Return_append_node(ir_node *ret, ir_node *node) return pos; } -ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset) +ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, + ir_node *old_sp, int offset, int align) { be_incsp_attr_t *a; ir_node *irn; ir_node *in[1]; in[0] = old_sp; - irn = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, sizeof(in) / sizeof(in[0]), in); + irn = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, + sizeof(in) / sizeof(in[0]), in); a = init_node_attr(irn, 1); a->offset = offset; + a->align = align; be_node_set_flags(irn, -1, arch_irn_flags_ignore | arch_irn_flags_modify_sp); @@ -1110,6 +1115,13 @@ int be_get_IncSP_offset(const ir_node *irn) return a->offset; } +int be_get_IncSP_align(const ir_node *irn) +{ + const be_incsp_attr_t *a = get_irn_attr_const(irn); + assert(be_is_IncSP(irn)); + return a->align; +} + ir_node *be_spill(const arch_env_t *arch_env, ir_node *block, ir_node *irn) { ir_graph *irg = get_irn_irg(block); diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index ada6d1842..cc00d1855 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -259,7 +259,8 @@ ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_ * @return A new stack pointer increment/decrement node. * @note This node sets a register constraint to the @p sp register on its output. */ -ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset); +ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, + ir_node *old_sp, int offset, int align); /** Returns the previous node that computes the stack pointer. */ ir_node *be_get_IncSP_pred(ir_node *incsp); @@ -277,6 +278,7 @@ void be_set_IncSP_offset(ir_node *irn, int offset); /** Gets the offset from a IncSP node. */ int be_get_IncSP_offset(const ir_node *irn); +int be_get_IncSP_align(const ir_node *irn); /** Gets the call entity or NULL if this is no static call. */ ir_entity *be_Call_get_entity(const ir_node *call); diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index d5a2dc07b..903502a10 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -377,22 +377,23 @@ static void ia32_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent set_ia32_frame_ent(irn, ent); } -static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) { +static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) +{ const ia32_irn_ops_t *ops = self; - if (get_ia32_frame_ent(irn)) { - if (is_ia32_Pop(irn)) { - 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; - } - } + if (get_ia32_frame_ent(irn) == NULL) + return; - add_ia32_am_offs_int(irn, bias); + if (is_ia32_Pop(irn)) { + 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; + } } + add_ia32_am_offs_int(irn, bias); } static int ia32_get_sp_bias(const void *self, const ir_node *node) @@ -496,7 +497,7 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ if (env->flags.try_omit_fp) { /* simply remove the stack frame here */ - curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK); + curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0); add_irn_dep(curr_sp, *mem); } else { const ia32_isa_t *isa = (ia32_isa_t *)env->isa; @@ -1632,6 +1633,7 @@ static ia32_isa_t ia32_isa_template = { &ia32_gp_regs[REG_ESP], /* stack pointer register */ &ia32_gp_regs[REG_EBP], /* base pointer register */ -1, /* stack direction */ + 16, /* stack alignment */ NULL, /* main environment */ 7, /* costs for a spill instruction */ 5, /* costs for a reload instruction */ @@ -2127,6 +2129,8 @@ static lc_opt_enum_int_var_t gas_var = { static const lc_opt_table_entry_t ia32_options[] = { LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var), + LC_OPT_ENT_INT("stackalign", "set stack alignment for calls", + &ia32_isa_template.arch_isa.stack_alignment), LC_OPT_LAST }; diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index 46b45b2f0..8ef88ef2e 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -606,6 +606,7 @@ static mips_isa_t mips_isa_template = { &mips_gp_regs[REG_SP], &mips_gp_regs[REG_FP], -1, /* stack direction */ + 1, /* stack alignment for calls */ NULL, /* main environment */ 7, /* spill costs */ 5, /* reload costs */ diff --git a/ir/be/ppc32/bearch_ppc32.c b/ir/be/ppc32/bearch_ppc32.c index c5e3c6b99..89b3c61ad 100644 --- a/ir/be/ppc32/bearch_ppc32.c +++ b/ir/be/ppc32/bearch_ppc32.c @@ -649,6 +649,7 @@ static ppc32_isa_t ppc32_isa_template = { &ppc32_gp_regs[REG_R1], /* stack pointer */ &ppc32_gp_regs[REG_R31], /* base pointer */ -1, /* stack is decreasing */ + 1, /* call stack alignment */ NULL, /* main environment */ 7, /* spill costs */ 5, /* reload costs */ -- 2.20.1