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.