aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorChung-Lin Tang <cltang@codesourcery.com>2014-03-11 09:04:54 +0000
committerChung-Lin Tang <cltang@gcc.gnu.org>2014-03-11 09:04:54 +0000
commit747425d0e31ea9f57da6b5559502987f8e1b391a (patch)
tree535b8b0a71e28af5edc65d5993c80497280af179 /gcc/config
parent8955706a6994416e89c497cf407830e6172b1051 (diff)
downloadgcc-747425d0e31ea9f57da6b5559502987f8e1b391a.zip
gcc-747425d0e31ea9f57da6b5559502987f8e1b391a.tar.gz
gcc-747425d0e31ea9f57da6b5559502987f8e1b391a.tar.bz2
nios2.c (machine_function): Add fp_save_offset field.
2014-03-11 Chung-Lin Tang <cltang@codesourcery.com> * config/nios2/nios2.c (machine_function): Add fp_save_offset field. (nios2_compute_frame_layout): Add calculation of cfun->machine->fp_save_offset. (nios2_expand_prologue): Correct setting of frame pointer register in prologue. (nios2_expand_epilogue): Update recovery of stack pointer from frame pointer accordingly. (nios2_initial_elimination_offset): Update calculation of offset for eliminating to HARD_FRAME_POINTER_REGNUM. From-SVN: r208472
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/nios2/nios2.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
index 19eedf4..edf9a61 100644
--- a/gcc/config/nios2/nios2.c
+++ b/gcc/config/nios2/nios2.c
@@ -81,8 +81,10 @@ struct GTY (()) machine_function
int args_size;
/* Number of bytes needed to store registers in frame. */
int save_reg_size;
- /* Offset from new stack pointer to store registers. */
+ /* Offset from new stack pointer to store registers. */
int save_regs_offset;
+ /* Offset from save_regs_offset to store frame pointer register. */
+ int fp_save_offset;
/* != 0 if frame layout already calculated. */
int initialized;
};
@@ -390,6 +392,17 @@ nios2_compute_frame_layout (void)
}
}
+ cfun->machine->fp_save_offset = 0;
+ if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
+ {
+ int fp_save_offset = 0;
+ for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
+ if (save_mask & (1 << regno))
+ fp_save_offset += 4;
+
+ cfun->machine->fp_save_offset = fp_save_offset;
+ }
+
save_reg_size = NIOS2_STACK_ALIGN (save_reg_size);
total_size += save_reg_size;
total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
@@ -450,8 +463,8 @@ nios2_expand_prologue (void)
{
unsigned int regno;
int total_frame_size, save_offset;
- int sp_offset; /* offset from base_reg to final stack value. */
- int fp_offset; /* offset from base_reg to final fp value. */
+ int sp_offset; /* offset from base_reg to final stack value. */
+ int save_regs_base; /* offset from base_reg to register save area. */
rtx insn;
total_frame_size = nios2_compute_frame_layout ();
@@ -468,8 +481,7 @@ nios2_expand_prologue (void)
gen_int_mode (cfun->machine->save_regs_offset
- total_frame_size, Pmode)));
RTX_FRAME_RELATED_P (insn) = 1;
-
- fp_offset = 0;
+ save_regs_base = 0;
sp_offset = -cfun->machine->save_regs_offset;
}
else if (total_frame_size)
@@ -478,16 +490,16 @@ nios2_expand_prologue (void)
gen_int_mode (-total_frame_size,
Pmode)));
RTX_FRAME_RELATED_P (insn) = 1;
- fp_offset = cfun->machine->save_regs_offset;
+ save_regs_base = cfun->machine->save_regs_offset;
sp_offset = 0;
}
else
- fp_offset = sp_offset = 0;
+ save_regs_base = sp_offset = 0;
if (crtl->limit_stack)
nios2_emit_stack_limit_check ();
- save_offset = fp_offset + cfun->machine->save_reg_size;
+ save_offset = save_regs_base + cfun->machine->save_reg_size;
for (regno = LAST_GP_REG; regno > 0; regno--)
if (cfun->machine->save_mask & (1 << regno))
@@ -498,9 +510,10 @@ nios2_expand_prologue (void)
if (frame_pointer_needed)
{
+ int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
stack_pointer_rtx,
- gen_int_mode (fp_offset, Pmode)));
+ gen_int_mode (fp_save_offset, Pmode)));
RTX_FRAME_RELATED_P (insn) = 1;
}
@@ -555,7 +568,9 @@ nios2_expand_epilogue (bool sibcall_p)
if (frame_pointer_needed)
{
/* Recover the stack pointer. */
- insn = emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
+ insn = emit_insn (gen_add3_insn
+ (stack_pointer_rtx, hard_frame_pointer_rtx,
+ gen_int_mode (-cfun->machine->fp_save_offset, Pmode)));
cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
(total_frame_size
- cfun->machine->save_regs_offset));
@@ -772,7 +787,8 @@ nios2_initial_elimination_offset (int from, int to)
/* If we are asked for the frame pointer offset, then adjust OFFSET
by the offset from the frame pointer to the stack pointer. */
if (to == HARD_FRAME_POINTER_REGNUM)
- offset -= cfun->machine->save_regs_offset;
+ offset -= (cfun->machine->save_regs_offset
+ + cfun->machine->fp_save_offset);
return offset;
}