I'll be looking into this but I thought that GO_IF_LEGITIMATE_ADDRESS
is for branches ?

This is not my case. I've simplified my test case into:

struct test {
    const char  *name;          /* full name */
    char        a;          /* symbol */
    signed char     b;
    unsigned short  c;          /* creation/c mask value */
};

extern struct test tab[];       /* the master list of tabter types */

void bar(unsigned short);

int main(void)
{
    int i;
    for (i=0;i<128;i++)
        if(tab[i].b)
            bar(tab[i].c);
}

The compiler loads tab[i].b and, to do so, loads up the address of &tab[i].b.

Then, when it wants to pass the value of tab[i].c it tries to do a
ldhu r5, 1(r10)

which is wrong in our case. Because it is loading a HI, the offset
must be a multiple of 2. It so happens that currently the problem is
arrising when considering this RTX

(insn:HI 77 76 124 struct2.c:17 (set (reg:DI 8 r8)
        (sign_extend:DI (mem:HI (plus:DI (reg:DI 48 r48 [orig:134
ivtmp.19 ] [134])
                    (const_int 1 [0x1])) [0 S2 A16]))) 61
{extendhidi2_cyc64} (nil))

Am I wrong to think that, in this case, GO_IF_LEGITIMATE_ADDRESS would
not help? On my architecture, we actually have a scratch register we
can use.

I'm thinking of using a define_peephole2 to correct this as a later
pass, taking the address and moving it into a register thus getting a
0 offset.

I just feel that is so ugly, there should be a way to tell GCC that a
mem cannot be defined with:
(mem:HI (plus:DI (reg:DI 48 r48 [orig:134 ivtmp.19 ] [134])
                    (const_int 1 [0x1])) [0 S2 A16]))) 61
{extendhidi2_cyc64} (nil))

in the case of a HI because of the constant (and then same for SI/DI of course).

Thanks again for your help, and I will continue looking into this,
Jc

On Tue, Jun 9, 2009 at 6:36 PM, Dave
Korn<dave.korn.cyg...@googlemail.com> wrote:
> Jean Christophe Beyler wrote:
>> Dear all,
>>
>> I've moved forward on this issue. Again, the problem is not that the
>> data is not aligned but that the compiler tries to generate this
>> instruction:
>>
>> (set (reg:HI 141) (mem/s/j:HI (plus:DI (reg:DI 134 [ ivtmp.23 ])
>>          (const_int 1 [0x1])) [0 <variable>.geno+0 S2 A16]))
>>
>> And, in my target architecture, this is not authorized. I want to
>> transform this into:
>>
>> (set (reg:DI 135) (plus:DI (reg:DI 134 [ ivtmp.23 ])
>>          (const_int 1 [0x1])) [0 <variable>.geno+0 S2 A16]))
>> (set (reg:HI 141) (mem/s/j:HI (reg:DI 135))
>>
>>
>> I've tried playing with define_expand, I can detect this problem, I
>> can emit my first move and then the second but for some reason, the
>> compiler reassembles them back together.
>>
>> Any ideas why I am getting that? Am I doing anything wrong? After I
>> expand this, I use the DONE macro...
>
>
>  How about forbidding the form you don't allow in GO_IF_LEGITIMATE_ADDRESS?
>
>    cheers,
>      DaveK
>

Reply via email to