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<[email protected]> 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
>