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 <wil...@codesourcery.com>:
> 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
>

Reply via email to