This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: target/5828: gcc-3.0.4 on arm : floating point registers incorrectly reloaded
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: jeroen dobbelaere <jeroen dot dobbelaere at acunia dot com>
- Cc: gcc-patches at gcc dot gnu dot org, gcc-gnats at gcc dot gnu dot org, Richard dot Earnshaw at arm dot com
- Date: Thu, 14 Mar 2002 15:13:28 +0000
- Subject: Re: target/5828: gcc-3.0.4 on arm : floating point registers incorrectly reloaded
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
Richard Earnshaw wrote:
> + 2002-03-04 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
> +
> + * config/arm/arm.c (arm_output_epilogue): bug 5828 : offset
> + must start at 0 in stead of 12.
> +
>
> This patch is incorrect.
[...]
> 2) It is cludge to work around another bug further down the function.
Having thought about this some more, I've revised my opinion. This a
slightly different, but equally valid, way of looking at the problem.
However, it slightly confuses the way the offsets are being calculated.
I've committed the following patch to correct the problem:
2002-03-14 Richard Earnshaw <rearnsha@arm.com>
Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
PR target/5828
* arm.c (arm_output_epilogue): Fix floating-point register save
adjustment when using a frame pointer.
Index: arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.197
diff -p -r1.197 arm.c
*** arm.c 2002/03/13 05:42:33 1.197
--- arm.c 2002/03/14 15:03:26
*************** arm_output_epilogue (really_return)
*** 7467,7474 ****
int reg;
unsigned long saved_regs_mask;
unsigned long func_type;
! /* If we need this, then it will always be at least this much. */
! int floats_offset = 12;
rtx operands[3];
int frame_size = get_frame_size ();
FILE * f = asm_out_file;
--- 7467,7475 ----
int reg;
unsigned long saved_regs_mask;
unsigned long func_type;
! /* Floats_offset is the offset from the "virtual" frame. In an APCS
! frame that is $fp + 4 for a non-variadic function. */
! int floats_offset = 0;
rtx operands[3];
int frame_size = get_frame_size ();
FILE * f = asm_out_file;
*************** arm_output_epilogue (really_return)
*** 7505,7510 ****
--- 7506,7514 ----
saved_regs_mask = arm_compute_save_reg_mask ();
+ /* XXX We should adjust floats_offset for any anonymous args, and then
+ re-adjust vfp_offset below to compensate. */
+
/* Compute how far away the floats will be. */
for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
if (saved_regs_mask & (1 << reg))
*************** arm_output_epilogue (really_return)
*** 7512,7517 ****
--- 7516,7523 ----
if (frame_pointer_needed)
{
+ int vfp_offset = 4;
+
if (arm_fpu_arch == FP_SOFT2)
{
for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
*************** arm_output_epilogue (really_return)
*** 7519,7525 ****
{
floats_offset += 12;
asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
! reg, FP_REGNUM, floats_offset);
}
}
else
--- 7525,7531 ----
{
floats_offset += 12;
asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
! reg, FP_REGNUM, floats_offset - vfp_offset);
}
}
else
*************** arm_output_epilogue (really_return)
*** 7536,7542 ****
if (start_reg - reg == 3)
{
asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
! reg, FP_REGNUM, floats_offset);
start_reg = reg - 1;
}
}
--- 7542,7548 ----
if (start_reg - reg == 3)
{
asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
! reg, FP_REGNUM, floats_offset - vfp_offset);
start_reg = reg - 1;
}
}
*************** arm_output_epilogue (really_return)
*** 7545,7551 ****
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
! FP_REGNUM, floats_offset);
start_reg = reg - 1;
}
}
--- 7551,7557 ----
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
! FP_REGNUM, floats_offset - vfp_offset);
start_reg = reg - 1;
}
}
*************** arm_output_epilogue (really_return)
*** 7554,7560 ****
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
! FP_REGNUM, floats_offset);
}
/* saved_regs_mask should contain the IP, which at the time of stack
--- 7560,7566 ----
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
! FP_REGNUM, floats_offset - vfp_offset);
}
/* saved_regs_mask should contain the IP, which at the time of stack