Patchwork [6/9] Emit the prologue/epilogue using frame offsets.

login
register
mail settings
Submitter H.J. Lu
Date Aug. 5, 2010, 6:30 p.m.
Message ID <AANLkTi=Y6GsEgZ11mCF5OXXvSSU1bAXfhUt9iQH-u8gA@mail.gmail.com>
Download mbox | patch
Permalink /patch/61012/
State New
Headers show

Comments

H.J. Lu - Aug. 5, 2010, 6:30 p.m.
On Thu, Aug 5, 2010 at 11:26 AM, Richard Henderson <rth@twiddle.net> wrote:
> On 08/05/2010 11:19 AM, H.J. Lu wrote:
>> It is interesting. I saw it on 32bit host with 32bit HOST_WIDE_INT. Is it
>> a signed vs. unsigned issue? stack_alignment_needed is unsigned.
>
> Yes, signed is the issue.  Previously we'd have
>
>  -stack_alignment_needed / 8
>  -256u / 8
>  0xffffff00u / 8
>  0x1fffffe0u
>
> If you receive a memory layout such that the stack is <= 0x1fffffff,
> the program will happen to work.  With the cast we get -32 and not
> a large unsigned number, which is what we really wanted.
>

I think this patch is clearer and also fixes the issue.
Richard Henderson - Aug. 5, 2010, 6:56 p.m.
On 08/05/2010 11:30 AM, H.J. Lu wrote:
> I think this patch is clearer and also fixes the issue.

> -	  addr = GEN_INT (-crtl->stack_alignment_needed / BITS_PER_UNIT);
> +	  addr = GEN_INT (-(crtl->stack_alignment_needed
> +			    / BITS_PER_UNIT));

Not quite.  Here you get 0xfffffff0u not -16, which is different
for 64-bit HOST_WIDE_INT.  Which technically works, but the unwind
info is larger since -16 encodes smaller.


r~

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d809d44..ecccef1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -8639,7 +8639,8 @@  ix86_emit_save_reg_using_mov (enum machine_mode mode, unsi
gned int regno,
 	     reference to the locations within the frame.  Instead,
 	     simply compute the location of the aligned frame from
 	     the frame pointer.  */
-	  addr = GEN_INT (-crtl->stack_alignment_needed / BITS_PER_UNIT);
+	  addr = GEN_INT (-(crtl->stack_alignment_needed
+			    / BITS_PER_UNIT));
 	  addr = gen_rtx_AND (Pmode, hard_frame_pointer_rtx, addr);
 	  addr = plus_constant (addr, -cfa_offset);