Question on ARM legitimate address for DImode

Richard Earnshaw rearnsha@arm.com
Tue Dec 21 10:12:00 GMT 2010


On Tue, 2010-12-21 at 12:12 +0800, Jie Zhang wrote:
> Hi,
> 
> While working on a bug, I found some code in ARM port that I don't 
> understand.
> 
> In ARM_LEGITIMIZE_RELOAD_ADDRESS and arm_legitimize_address, we allow a 
> very small offset for DImode addressing.
> 
> In ARM_LEGITIMIZE_RELOAD_ADDRESS:
> 
> if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT))     \
>    low = ((val & 0xf) ^ 0x8) - 0x8;                               \
> 
> In arm_legitimize_address
> 
>    /* VFP addressing modes actually allow greater offsets, but for
>       now we just stick with the lowest common denominator.  */
>    if (mode == DImode
>        || ((TARGET_SOFT_FLOAT || TARGET_VFP) && mode == DFmode))
>      {
>        low_n = n & 0x0f;
>        n &= ~0x0f;
>        if (low_n > 4)
>          {
>            n += 16;
>            low_n -= 16;
>          }
>      }
> 
> AFAIK, we could use two LDRs, or one LDRD, or one VLDR to access DImode 
> in memory when the address is in the form of (REG + CONST_INT). The 
> offset ranges for these three cases are:
> 
> LDR  -4095,4091
> LDRD -255,255
> VLDR -1020,1020 && (ADDR & 3) == 0

The original code was designed to exploit LDM(IA,IB,DB,DA) which would
have the offset ranges described.  On earlier ARM chips (certainly up to
and including ARM7TDMI) it was a significant win to do it that way (add
a constant to the address register and then use LDM was faster than two
LDR instructions).

That's no-longer true on modern chips, LDM is often slower than
individual LDR insns now.


> 
> so the lowest common denominator is
> 
> -1020,1020 && (ADDR & 3) == 0 if ! TARGET_LDRD
>   -255,255  && (ADDR & 3) == 0 if TARGET_LDRD
> 
> Both are much larger than what we have now in the ARM port.
> 
> Did I miss some other cases? That two pieces of code are rather old 
> (more than 15 years). The main code was added by
> 
> svn: revision 7536 by erich, Thu Jun 23 16:02:41 1994 UTC in arm.h
> git: fac435147512513c1b8fa55bee061c8e3a767ba9
> log: (LEGITIMIZE_ADDRESS): Push constants that will never be legitimate 
> -- symbols
>       and labels -- into registers.  Handle DImode better.
> 
> I checked out that revision to take a look but didn't find an obvious 
> reason for such small index range. Did I miss something tricky?
> 
> If there is nothing I missed, I'd like to propose the attached patch.
> 
> 
> Regards,




More information about the Gcc mailing list