This is the mail archive of the gcc@gcc.gnu.org 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] |
Other format: | [Raw text] |
I am having a great deal of trouble getting register elimination (and stack frame layouts in general) working properly on my architecture. There is some fundamental issue I'm simply not getting here. My architecture is a fairly vanilla RISC system with a link pointer. The stack frame layout I'm aiming for looks like this: hi incoming_params ================== ap callee_saves ------------------ local_vars local_vars_padding ------------------ fp outgoing_params lo ------------------ sp The docs says that because I don't know where the locals are until I know how big callee_saves is, I have to use the following setup: #define STACK_POINTER_REGNUM SP_REG #define FRAME_POINTER_REGNUM FP_REG /* virtual frame pointer */ #define HARD_FRAME_POINTER_REGNUM R6_REG /* real frame pointer */ #define ARG_POINTER_REGNUM AP_REG /* virtual argument pointer */ AP_REG and FP_REG are fake registers (values 27 and 28 respectively; different from R6_REG and SP_REG). These get eliminated into either the stack or r6 as follows: #define ELIMINABLE_REGS \ {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }} This is all utterly standard, and mostly stolen from other ports... except I can't make it work, in various weird ways. Weirdness (1): I never see ARG_POINTER_REGNUM used to access arguments. The compiler seems to want to access function arguments via FRAME_POINTER_REGNUM plus a small value, which means they overlap the locals. (It's definitely using the same numeric ranges. It looks like it's trying to use ARG_POINTER_REGNUM but is getting the wrong register.) Weirdness (2): the following test function generates code with tries to copy AP_REG into a register without eliminating it. void* return_local(void) { int i; return &i; } It turns into the following RTL: (insn 17 2 12 2 (set (reg/i:SI 0 r0) (reg:SI 27 ?ap)) test.c:14 4 (nil)) (insn 12 17 15 2 (use (reg/i:SI 0 r0)) test.c:14 -1 (nil)) Why isn't elimination happening in this situation? And why is AP_REG being used here at all? I've been looking at the various backends, but they're not very helpful --- they're all rather different, and I can't see anything they're doing which I'm not or vice versa. However, I am particularly perturbed by the following comment from the MCore port: /* Note that the name `fp' is horribly misleading since `fp' is in fact only the argument-and-return-context pointer. */ I don't know whether this is just talking about the MCore, or gcc in general --- I find it interesting that most backends which use a fake frame pointer seem to end up with FRAME_POINTER_REGNO and HARD_FRAME_POINTER_REGNO pointing at different addresses. If anyone can offer any suggestions as to what I'm doing wrong --- or, better still, point me at more in-depth reading on how all this is supposed to work! -- ââââ ïïïïïïïïïïïïïï âââââ http://www.cowlark.com âââââ â "Every planet is weird. I spent six weeks on a moon where the â principal form of recreation was juggling geese. Baby geese. Goslings. â They were juggled." --- Firefly, _Our Mrs. Reynolds_
Attachment:
signature.asc
Description: OpenPGP digital signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |