>Peter Barada wrote:
>> I'd like to make the reload look like:
>> (set (reg:SI y) (plus:SI (reg_SI 16) (const_int 32832)))
>> (set (reg:DF x) (mem:DF (reg:SI y)))
>
>Reload already knows how to make this transformation, so it should not 
>be necessary to resort to LEGITIMIZE_RELOAD_ADDRESS.  This is only 
>needed for target specific tricks that reload can not and does not know 
>about.
>

I figured out how to make it work using LEGITIMIZE_RELOAD_ADDRESS(at
least for gcc-3.4.3) via:

/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value
   to replace the input X, or NULL_RTX if no replacement is called
   for.  If a new X is returned, then goto WIN in the invoking macro.

   Reload will try to handle large displacements off a base register
   by pushing the displacement into a register and using mode6,
   but this doesn't work for the ColdFire FPU, so in that case, if the
   address is not valid for the mode, and is either mode 5 or mode 6,
   then push the *entire* address into a register and use mode 2 to
   access the value. */

rtx
m68k_legitimize_reload_address (rtx *x, enum machine_mode mode,
        int opnum, int type, int ind_levels ATTRIBUTE_UNUSED)
{
  /* If the address is valid for 'mode', accept it.  */
  if (strict_memory_address_p(mode, *x))
    {
      return NULL_RTX;
    }

  /* The ColdFire v4e can't handle FP mode 6 addresses.  Unfortunately
     reload tries to remap a mode 5 address with the offset out of
     range into a mode 6.  Push an FP mode 5 with displacement out of
     range or mode 6 address into a register and use mode 2 addressing
     instead. */ 
  if (TARGET_CFV4E && GET_MODE_CLASS (mode) == MODE_FLOAT
      && GET_CODE (*x) == PLUS
      && !(GET_CODE (XEXP (*x, 0)) == REG
           && ((GET_CODE (XEXP (*x, 1)) == CONST_INT
                && (INTVAL (XEXP (*x, 1)) >= -32768
                    && INTVAL (XEXP (*x, 1)) <= 32767)))))
    {
      push_reload (*x, NULL_RTX, x,
                   NULL, BASE_REG_CLASS, GET_MODE (*x), VOIDmode, 0, 0,
                   opnum, type);
      return *x;
    }

  return NULL_RTX;
}

Hopefully I got it right.  If not, yell. :)

>See the code in find_reloads_address with the comment
>   /* If we have address of a stack slot but it's not valid because the
>      displacement is too large, compute the sum in a register.
>
>The problem here seems to be that double_reg_address_ok is true, but you 
>don't want it to be true.  It can only be true if 
>GO_IF_LEGITIMATE_ADDRESS accept REG+REG+4.  Perhaps the problem here is 
>that a double address reg is OK for integer loads, but not for FP loads, 
>in which case the double_address_reg_ok logic in reloads needs to be 
>generalized a bit.  Maybe an array based on mode instead of a single 
>variable?  Or maybe just int and fp versions are good enough for now.

For ColdFire v4e, FP loads and stores can not use REG+REG addressing.

I think you are correct that this current hack can be improved by
making an array of mode to determine if double_reg_address_ok should
be true, but I think in the end that a more flexible scheme be thought
about since this isn't the *only* peculiarity of the ColdFire.  One is
that pc-relative addressing is only available on the *source*, not the
destination, and currently GO_IF_LEGITIMATE_ADDRESS nor
LEGITIMIZE_ADDRESS have no way of know if its a source or destination.

Unfortunately I don't have any spare time to try that approach this
week.  If I can find the time next week, I'll put together a patch
against mainline that addresses this, but first I'd have to reproduce
the problem there(which will give a testcase).

-- 
Peter Barada
[EMAIL PROTECTED]

Reply via email to