On Jun 19, 2012, at 6:47 PM, Richard Henderson wrote:

> On 2012-06-18 05:22, Tristan Gingold wrote:
>> +/* Output assembly code to get the establisher frame (Windows x64 only).
>> +   This corresponds to what will be computed by Windows from Frame Register
>> +   and Frame Register Offset fields of the UNWIND_INFO structure.  Since
>> +   these values are computed very late (by ix86_expand_prologue), we cannot
>> +   express this using only RTL.  */
>> +
>> +const char *
>> +ix86_output_establisher_frame (rtx target)
>> +{
>> +  if (!frame_pointer_needed)
>> +    {
>> +      /* Note that we have advertized an lea operation.  */
>> +      output_asm_insn ("lea{q}\t{0(%%rsp), %0|%0, 0[rsp]}", &target);
>> +    }
>> +  else
>> +    {
>> +      rtx xops[3];
>> +      struct ix86_frame frame;
>> +
>> +      /* Recompute the frame layout here.  */
>> +      ix86_compute_frame_layout (&frame);
>> +
>> +      /* Closely follow how the frame pointer is set in
>> +     ix86_expand_prologue.  */
>> +      xops[0] = target;
>> +      xops[1] = hard_frame_pointer_rtx;
>> +      if (frame.hard_frame_pointer_offset == frame.reg_save_offset)
>> +    xops[2] = GEN_INT (0);
>> +      else
>> +    xops[2] = GEN_INT (-(frame.stack_pointer_offset
>> +                         - frame.hard_frame_pointer_offset));
>> +      output_asm_insn ("lea{q}\t{%a2(%1), %0|%0, %a2[%1]}", xops);
> 
> This is what register elimination is for; the value substitution happens
> during reload.
> 
> Now, one *could* add a new pseudo-hard-register for this (we support as
> many register eliminations as needed), but before we do that we need to
> decide if we can adjust the soft frame pointer to be the value required.
> If so, you can then rely on the existing __builtin_frame_address.  Which
> is a very attractive sounding solution.  I'm 99% moving the sfp will work.

One possibly naive question: the current code to expand __builtin_frame_address 
is:

  /* For a zero count with __builtin_return_address, we don't care what
     frame address we return, because target-specific definitions will
     override us.  Therefore frame pointer elimination is OK, and using
     the soft frame pointer is OK.

     For a nonzero count, or a zero count with __builtin_frame_address,
     we require a stable offset from the current frame pointer to the
     previous one, so we must use the hard frame pointer, and
     we must disable frame pointer elimination.  */
  if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
    tem = frame_pointer_rtx;
  else
    {
      tem = hard_frame_pointer_rtx;

      /* Tell reload not to eliminate the frame pointer.  */
      crtl->accesses_prior_frames = 1;
    }

So whatever we do with the sfp, the builtin will always returns %rbp - which is 
not what we expect.

This however opens two tracks:

1) Implement the __builtin_establisher_frame with frame_pointer_rtx
2) If accesses_prior_frames is set, makes %rbp be the establisher frame.

I will pursue the later.

Tristan.

Reply via email to