How to legitimize the reload address?

Jeff Law law@redhat.com
Wed May 21 16:46:00 GMT 2008


Mohamed Shafi wrote:
> On Wed, May 21, 2008 at 1:42 AM, Jeff Law <law@redhat.com> wrote:
>> Ian Lance Taylor wrote:
>>> "Mohamed Shafi" <shafitvm@gmail.com> writes:
>>>
>>>> For the 16 bit target that i am currently porting can have only
>>>> positive offsets less than 0x100. (unsigned 8 bit) for offset
>>>> addressing mode.
>>> I would expect reload to be able to handle this kind of thing anyhow,
>>> assuming you define GO_IF_LEGITIMATE_ADDRESS correctly.  reload should
>>> automatically try loading an out of range offset into a register.
>> Agreed.
>>
>> Typically if there are problems in this area it is because the port hasn't
>> properly defined secondary reloads, or the valid offsets are not consistent
>> within a machine mode.
>>
>> Mohamed, without more details, there's not much we can do to help you.
>>
>     I am sure that i have written GO_IF_LEGITIMATE_ADDRESS correctly.
> What i have in my port is something similar to mcore back-end. These
> are the relevant parts:
> 
>   else if (GET_CODE (X) == PLUS)
>     {
>       rtx xop0 = XEXP (X,0);
>       rtx xop1 = XEXP (X,1);
> 
>       if (BASE_REGISTER_RTX_P (xop0))
>         return legitimate_index_p (mode, xop1);
>    }
> 
> static int
> legitimate_index_p (enum machine_mode mode, rtx OP)
> {
>   if (GET_CODE (OP) == CONST_INT)
>     {
>       if (GET_MODE_SIZE (mode) >= 4
>           && (((unsigned)INTVAL (OP)) % 4) == 0
>           &&  ((unsigned)INTVAL (OP)) <= 0x0100)
>         return 1;
> 
>       if (GET_MODE_SIZE (mode) == 2
>           && (((unsigned)INTVAL (OP)) % 2) == 0
>           &&  ((unsigned)INTVAL (OP)) <= 0x0100)
>         return 1;
> 
>       if (GET_MODE_SIZE (mode) == 1
>           && ((unsigned)INTVAL (OP)) <= 0x0100)
>         return 1;
>     }
> 
>   return 0;
> }
> 
> 
> The compiler is crashing in change_address_1, at emit-rtl.c
> ...
>   if (validate)
>     {
>       if (reload_in_progress || reload_completed)
> 	gcc_assert (memory_address_p (mode, addr));
>       else
> 	addr = memory_address (mode, addr);
>     }
> ....
> 
> 
> Everything starts when cleanup_subreg_operands() is called from
> reload() for the following pattern.
> 
> (set (subreg:HI (mem:SI (plus:HI (reg:HI 12 [SP]) (const_int 256)) 2)
>        (reg:HI 3))
> 
> and then this becomes
> 
> (set (mem:HI (plus:HI (reg:HI 12 [SP] ) (const_int 258)))
>        (reg:HI 3))
> 
> This pattern is not legitimate due to out of range offset.
> Will i be able to overcome this if i write LEGITIMIZE_RELOAD_ADDRESS
> or LEGITIMIZE_ADDRESS
You have a (subreg (mem)) expression.  The mem part of that expression 
should have been reloaded into a register.    You probably want to look 
at your reload debugging dumps to see how/why that's not happening properly.

Using LEGITIMIZE_RELOAD_ADDRESS is definitely not the way to solve this 
problem.  It's intended solely as a means to optimize how reload 
generates code for certain cases.   LEGITIMIZE_ADDRESS won't have an 
affect at this stage in the compiler.

jeff
> 
> Thank you for your time.

> 
> Regards,
> Shafi



More information about the Gcc mailing list