Commit 5251caf2 by Michael Meissner

Fix bug when large stack frames (> 32k) are used, and saving both GP and FP registers.

From-SVN: r2840
parent 2649b2ee
...@@ -3914,7 +3914,7 @@ save_restore (file, gp_op, gp_2word_op, fp_op) ...@@ -3914,7 +3914,7 @@ save_restore (file, gp_op, gp_2word_op, fp_op)
unsigned long fmask = current_frame_info.fmask; unsigned long fmask = current_frame_info.fmask;
unsigned long gp_offset; unsigned long gp_offset;
unsigned long fp_offset; unsigned long fp_offset;
unsigned long max_offset; unsigned long min_offset;
char *base_reg; char *base_reg;
if (mask == 0 && fmask == 0) if (mask == 0 && fmask == 0)
...@@ -3923,17 +3923,17 @@ save_restore (file, gp_op, gp_2word_op, fp_op) ...@@ -3923,17 +3923,17 @@ save_restore (file, gp_op, gp_2word_op, fp_op)
base_reg = reg_names[STACK_POINTER_REGNUM]; base_reg = reg_names[STACK_POINTER_REGNUM];
gp_offset = current_frame_info.gp_sp_offset; gp_offset = current_frame_info.gp_sp_offset;
fp_offset = current_frame_info.fp_sp_offset; fp_offset = current_frame_info.fp_sp_offset;
max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset; min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset;
/* Deal with calling functions with a large structure. */ /* Deal with calling functions with a large structure. */
if (max_offset >= 32768) if (min_offset >= 32768)
{ {
char *temp = reg_names[MIPS_TEMP2_REGNUM]; char *temp = reg_names[MIPS_TEMP2_REGNUM];
fprintf (file, "\tli\t%s,%ld\n", temp, max_offset); fprintf (file, "\tli\t%s,%ld\n", temp, min_offset);
fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg); fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg);
base_reg = temp; base_reg = temp;
gp_offset = max_offset - gp_offset; gp_offset = min_offset - gp_offset;
fp_offset = max_offset - fp_offset; fp_offset = min_offset - fp_offset;
} }
/* Save registers starting from high to low. The debuggers prefer /* Save registers starting from high to low. The debuggers prefer
...@@ -3982,28 +3982,28 @@ save_restore_insns (store_p) ...@@ -3982,28 +3982,28 @@ save_restore_insns (store_p)
int store_p; /* true if this is prologue */ int store_p; /* true if this is prologue */
{ {
int regno; int regno;
rtx base_reg_rtx = stack_pointer_rtx; rtx base_reg_rtx = stack_pointer_rtx;
unsigned long mask = current_frame_info.mask; unsigned long mask = current_frame_info.mask;
unsigned long fmask = current_frame_info.fmask; unsigned long fmask = current_frame_info.fmask;
unsigned long gp_offset; unsigned long gp_offset;
unsigned long fp_offset; unsigned long fp_offset;
unsigned long max_offset; unsigned long min_offset;
if (mask == 0 && fmask == 0) if (mask == 0 && fmask == 0)
return; return;
gp_offset = current_frame_info.gp_sp_offset; gp_offset = current_frame_info.gp_sp_offset;
fp_offset = current_frame_info.fp_sp_offset; fp_offset = current_frame_info.fp_sp_offset;
max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset; min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset;
/* Deal with calling functions with a large structure. */ /* Deal with calling functions with a large structure. */
if (max_offset >= 32768) if (min_offset >= 32768)
{ {
base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
emit_move_insn (base_reg_rtx, GEN_INT (max_offset)); emit_move_insn (base_reg_rtx, GEN_INT (min_offset));
emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
gp_offset = max_offset - gp_offset; gp_offset = min_offset - gp_offset;
fp_offset = max_offset - fp_offset; fp_offset = min_offset - fp_offset;
} }
/* Save registers starting from high to low. The debuggers prefer /* Save registers starting from high to low. The debuggers prefer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment