- 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 = 1 << env->arch_env->stack_alignment;
+ int delta = (real_bias + ofs + between_size) & (alignment - 1);
+ 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;
+ }