Thanks Jim and Ian. I've added a secondary_reload which does this:
...
if (code == MEM)
{
if (fp_plus_const_operand(XEXP(x, 0), mode))
{
sri->icode = in_p ? CODE_FOR_reload_insi : CODE_FOR_reload_outsi;
return NO_REGS;
}
where fp_plus_const_operand is taken from the bfin port - it checks
that this is RTL of the form ((plus (reg const)). The .md file
contains:
---
(define_expand "reload_insi"
[(parallel [(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "memory_operand" "m"))
(clobber (match_operand:SI 2 "register_operand" "=a"))])]
""
{
fprintf(stderr, "reload_insi\n");
rtx plus_op = XEXP(operands[1], 0);
rtx fp_op = XEXP (plus_op, 0);
rtx const_op = XEXP (plus_op, 1);
rtx primary = operands[0];
rtx scratch = operands[2];
emit_move_insn (scratch, fp_op);
emit_insn (gen_addsi3 (scratch, scratch, const_op));
emit_move_insn (primary, gen_rtx_MEM(Pmode, scratch));
DONE;
}
)
(define_expand "reload_outsi"
[(parallel [(match_operand 0 "memory_operand" "=m")
(match_operand 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "=&a")])]
""
{
fprintf(stderr, "reload_outsi\n");
rtx plus_op = XEXP(operands[0], 0);
rtx fp_op = XEXP (plus_op, 0);
rtx const_op = XEXP (plus_op, 1);
rtx primary = operands[1];
rtx scratch = operands[2];
emit_move_insn (scratch, fp_op);
emit_insn (gen_addsi3 (scratch, scratch, const_op));
emit_move_insn (gen_rtx_MEM(Pmode, scratch), primary);
DONE;
}
)
---
The reload_insi is being called and is expanding into the correct code
but for some reason the reload_outsi never gets called. sri->icode is
being set correctly and propagates a few levels up but I couldn't
track it any further.
The s390 port does the reload in the same way as me. The bfin is
similar. I haven't looked further into GO_IF_LEGITIMATE_ADDRESS but
it's the next part to look at. It's a stripped down version of the
mmix one so it should be roughly OK.
I'm a bit confused with the documentation versus the ports. For
example, REGNO_MODE_CODE_OK_FOR_BASE_P doesn't appear to need a strict
form according to the documentation but the bfin port has a strict and
non-strict version. Most of the ports have a REG_OK_FOR_BASE_P macro
with strict and non-strict versions macro but it's not documented,
isn't used, and might have been removed around gcc 4.0.
Any ideas on why the reload_outsi above is being eaten?
Thanks,
-- Michael
2009/4/30 Jim Wilson <[email protected]>:
> Michael Hope wrote:
>>
>> HI there. I'm working on porting gcc to a new architecture which only
>> does indirect addressing - there is no indirect with displacement.
>
> The IA-64 target also has only indirect addressing. Well, it has some
> auto-increment addressing modes too, but that isn't relevant here. You
> could try looking at the IA-64 port to see why it works and yours doesn't.
>
>> 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.
>
> Since this is happening inside reload, first thing I would check is to make
> sure you handle REG_OK_STRICT correctly. Before reload, a pseudo-reg is a
> valid memory address. Inside reload, an unallocated pseudo-reg is actually
> a memory location, and hence can not be a valid memory address. This is
> controlled by REG_OK_STRICT.
>
> Jim
>