This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

hard_frame_pointer_rtx vs. register number


I am working on cleaning up Tensilica's port for Xtensa to contribute
back to GCC.  One of the hardest issues is that Xtensa may have an
incoming argument value in the register designated as the hard frame
pointer.  We hacked around this in EGCS 1.0.3 by telling GCC that these
were separate registers and then tweaking the reload pass to make sure
that they weren't both used at the same time.  I'm trying to find a
better solution.

I had previously thought that it would still be best to make it appear
that the incoming argument value was in a different register than the
hard frame pointer.  I ran into more problems with that, and I think I
see a new solution.  I would appreciate some feedback on whether this
will work:


For GCC's register allocation to handle this conflict properly, it needs
to know that the particular incoming argument register and the hard
frame pointer register are the same.  So, I am proposing to have a
single hard register for both purposes.

What stopped me from this before is the large amount of code in GCC that
treats the hard frame pointer register specially, e.g., assuming it is a
pointer into the stack and is aligned to STACK_BOUNDARY.  What I may
have missed is that most of these comparisons are of the form:

	reg == hard_frame_pointer_rtx

This seems to imply that if you create a REG rtx for register
HARD_FRAME_POINTER_REGNO without going through gen_rtx_REG, so that the
resulting rtx is _not_ canonicalized to hard_frame_pointer_rtx, then you
can keep other values in this register without having it subjected to
all the special treatment that the hard frame pointer gets.  In fact,
this already happens when reload determines that it doesn't need a frame
pointer, and uses the hard frame pointer register as an ordinary spill

Is this correct?  If I put an incoming argument in this register and
make sure that the rtx for that argument REG is different than
hard_frame_pointer_rtx, will it work (modulo any bugs in this area)?


I searched through all the GCC 3.0 sources looking for comparisons
against either HARD_FRAME_POINTER_REGNO or hard_frame_pointer_rtx. 
There were only a few suspicious bits of code, where it seems to me that
the code was incorrectly comparing the register number instead of
checking against hard_frame_pointer_rtx (assuming that my interpretation
above is correct).  The only show-stopper for what I want to do is in
cse.c in canon_hash().  The relevant code is:

	    && (global_regs[regno]
		    && ! fixed_regs[regno]
		    && regno != FRAME_POINTER_REGNUM
		    && regno != ARG_POINTER_REGNUM
		    && regno != STACK_POINTER_REGNUM
		    && GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
	    do_not_record = 1;
	    return 0;

It seems to me like this ought to be changed to:

	&& x != hard_frame_pointer_rtx

and for consistency, it might be good to change the other regno
comparisons as well.  Would that be an acceptable change?

(FYI: This is the "nicest" approach I have yet thought of for making the
Xtensa port work.  All of my previous attempts have required much uglier
hacks to the shared portions of GCC.)

If you can suggest other alternatives to handling this conflict between
an incoming argument register and the hard frame pointer register,
please let me know now!  I won't have time to reimplement this more than

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]