This is the mail archive of the
mailing list for the GCC project.
Re: Unexpected offsets when eliminating SP
- From: Michael Hope <michaelh at juju dot net dot nz>
- To: gcc at gcc dot gnu dot org
- Date: Sat, 9 May 2009 19:45:19 +1200
- Subject: Re: Unexpected offsets when eliminating SP
- References: <email@example.com>
Thanks for everybodys help. I've gotten things working so I thought
I'd quickly write it up.
The architecture I'm working on is deliberatly simple. It has:
* An accumulator
* Fourteen general purpose registers R10 to R1E
* X and Y cache registers each backed by non-coherent (!) caches
* A stack backed by the S cache
Memory can only be accessed by the X or Y registers. The
cache-coherency problem means you can really only use X unless you can
tell Y is far away - but that's a problem for another time. It also
means you can't use the S stack as a data stack as you can't address
it using X.
The only addressing is 32 bit word indirect, 8 bit with pre-decrement,
and 8 bit with post increment.
I allocated R1E to the data stack and R1D to the frame pointer. The
general purpose registers are in the DATA_REGS class while X and Y are
in ADDR_REGS. Y is marked as fixed to prevent it being used.
The implementation is:
* Set BASE_REG_CLASS to ADDR_REGS
* Set INDEX_REG_CLASS to NO_REGS to reject index addressing
* Implement GO_IF_LEGITIMATE_ADDRESS so that it accepts (mem x) but
rejects (mem (plus (reg const)) and the others
You can't set BASE_REG_CLASS to NO_REGS as (mem x) is treated as (mem
(plus (reg 0))
This works fine until you spill a variable. Spills generate offsets
relative to the frame pointer. This is OK providing your frame
pointer is a member of ADDR_REGS - mine isn't so the resulting fixup
generates a offset address which kills the compiler.
You can't pretend and put the FP in ADDR_REGS. A non-zero offset will
correctly be rejected by GO_IF_LEGITIMATE_ADDRESS and loaded into X,
but a zero offset will try to load from R1D.
The solution here is to copy the mc68hc11 and use
LEGITIMIZE_RELOAD_ADDRESS to recognise the offset and cause another
reload. This code:
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE(XEXP(x, 1)) == CONST_INT)
HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
push_reload(x, NULL_RTX, px, NULL,
ADDR_REGS, GET_MODE(x), VOIDmode, 0, 0, opnum, reload_type);
I tried TARGET_SECONDARY_RELOAD as well. Similar code to above would
correclty generate the code on an 'in' reload but for some reason the
code for the 'out' reload would never get inserted.
2009/4/29 Michael Hope <firstname.lastname@example.org>:
> HI there. ?I'm working on porting gcc to a new architecture which only
> does indirect addressing - there is no indirect with displacement.
> The problem is with spill locations in GCC 4.4.0. ?The elimination
> code correctly elimates the frame and args pointer and replaces it
> with register X. ?The problem is that it then generates indirect with
> offset loads to load spilt values.
> Normal usage such as:
> struct foo
> ?int a;
> ?int b;
> int bar(struct foo* p)
> ? return p->b;
> is correctly split into load X with p, add four, and then de-references.
> The RTL is generated after the IRA stage. ?GCC aborts in post reload
> with a 'instruction does not satisfy constraints' on:
> (insn 183 181 75 3 mandelbrot.c:117 (set (reg:SI 6 R11)
> ? ? ? ?(mem/c:SI (plus:SI (reg:SI 3 X)
> ? ? ? ? ? ? ? ?(const_int -8 [0xfffffffffffffff8])) [0 %sfp+-8 S4
> A32])) -1 (nil))
> The movsi it matches against is:
> (define_insn "movsi_insn"
> ?[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,rm,rm,rm,C, rm")
> ? ? ? ?(match_operand:SI 1 "general_operand" ? ? ? "r, m,I, i ,n, rm,C"))]
> ? LOADACC, %1\;STOREACC, %0
> ? LOADACC, %1\;STOREACC, %0
> ? LOADI, #%1\;STOREACC, %0
> ? LOADLONG, #%1\;STOREACC, %0
> ? LOADLONG, %1\;STOREACC, %0
> ? Foo
> ? Bar"
> I believe it fails on the constraints as the 'm' constraint misses as
> go_if_legitimate_address only supports (mem (reg)) and not (mem (plus
> I don't think I had this problem when working against 4.3.3 but I'm not sure.
> Could someone point me in the right direction please? ?Is it
> appropriate to ask such questions on this list?
> -- Michael