>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]