- return 0;
-}
-
-/**
- * Put all registers which are saved by the prologue/epilogue in a set.
- *
- * @param self The callback object.
- * @param s The result set.
- */
-static void ia32_abi_dont_save_regs(void *self, pset *s)
-{
- ia32_abi_env_t *env = self;
- if(env->flags.try_omit_fp)
- pset_insert_ptr(s, env->aenv->bp);
-}
-
-/**
- * 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 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 *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;
- const arch_env_t *arch_env = env->aenv;
-
- if (! env->flags.try_omit_fp) {
- ir_graph *irg =env->irg;
- ir_node *bl = get_irg_start_block(irg);
- ir_node *curr_sp = be_abi_reg_map_get(reg_map, arch_env->sp);
- ir_node *curr_bp = be_abi_reg_map_get(reg_map, arch_env->bp);
- ir_node *noreg = ia32_new_NoReg_gp(cg);
- ir_node *push;
-
- /* ALL nodes representing bp must be set to ignore. */
- be_node_set_flags(get_Proj_pred(curr_bp), BE_OUT_POS(get_Proj_proj(curr_bp)), arch_irn_flags_ignore);
-
- /* push ebp */
- push = new_rd_ia32_Push(NULL, irg, bl, noreg, noreg, *mem, curr_bp, curr_sp);
- curr_sp = new_r_Proj(irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
- *mem = new_r_Proj(irg, bl, push, mode_M, pn_ia32_Push_M);
-
- /* the push must have SP out register */
- 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);
- arch_set_irn_register(arch_env, curr_bp, arch_env->bp);
- be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
-
- /* beware: the copy must be done before any other sp use */
- curr_sp = be_new_CopyKeep_single(arch_env->sp->reg_class, irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
- be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), arch_env->sp);
- arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
- be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
-
- be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
- be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
-
- return arch_env->bp;
- }
-
- return arch_env->sp;
-}
-
-/**
- * Generate the routine epilogue.
- * @param self The callback object.
- * @param bl The block for the epilog
- * @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.
- *
- * All nodes which define registers in @p reg_map must keep @p reg_map current.
- */
-static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
-{
- ia32_abi_env_t *env = self;
- const arch_env_t *arch_env = env->aenv;
- ir_node *curr_sp = be_abi_reg_map_get(reg_map, arch_env->sp);
- ir_node *curr_bp = be_abi_reg_map_get(reg_map, arch_env->bp);
- ir_graph *irg = env->irg;
-
- if (env->flags.try_omit_fp) {
- /* simply remove the stack frame here */
- curr_sp = be_new_IncSP(arch_env->sp, irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
- } else {
- ir_mode *mode_bp = arch_env->bp->reg_class->mode;
-
- if (ia32_cg_config.use_leave) {
- ir_node *leave;
-
- /* leave */
- leave = new_rd_ia32_Leave(NULL, irg, bl, curr_bp);
- set_ia32_flags(leave, arch_irn_flags_ignore);
- curr_bp = new_r_Proj(irg, bl, leave, mode_bp, pn_ia32_Leave_frame);
- curr_sp = new_r_Proj(irg, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
- } else {
- ir_node *pop;
-
- /* the old SP is not needed anymore (kill the proj) */
- assert(is_Proj(curr_sp));
- kill_node(curr_sp);
-
- /* copy ebp to esp */
- curr_sp = be_new_Copy(&ia32_reg_classes[CLASS_ia32_gp], irg, bl, curr_bp);
- arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
- be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
-
- /* pop ebp */
- pop = new_rd_ia32_Pop(NULL, env->irg, bl, *mem, curr_sp);
- set_ia32_flags(pop, arch_irn_flags_ignore);
- curr_bp = new_r_Proj(irg, bl, pop, mode_bp, pn_ia32_Pop_res);
- curr_sp = new_r_Proj(irg, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
-
- *mem = new_r_Proj(irg, bl, pop, mode_M, pn_ia32_Pop_M);
- }
- arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
- arch_set_irn_register(arch_env, curr_bp, arch_env->bp);