This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/50705] Wrong assembly generated for bitwise AND for ppc 476


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50705

--- Comment #11 from SK <santoshkumar.a at gmail dot com> 2011-10-19 14:22:16 UTC ---
FILE::
/mm/page_alloc.c:5363
flags -> 0x3
HASH_EARLY - > 0x1

CODE::
if (flags & HASH_EARLY)

Assembly:
70307c44:       fe 0f e0 54     rlwinm  r0,r7,1,31,31

r7 = 0x3 = 0000 0000 0000 0000 0000 0000 0000 0011 (bits 0...31. So, bit 30 ==
1 and bit 31 == 1).

HASH_EARLY should ideally be seen by the compiler as 0000 0000 0000 0000 0000
0000 0000 0001 (bits 0...31. So, bit 31 == 1).

So, if in Little Endian mode, then in PowerPC terms the above "if" is testing
bit 31 of the flags field. 
In which case, the compiler should be generating assembly as: rlwinm 
r0,r7,0,31,31

However, it appears the compiler sees HASH_EARLY as 1000 0000 0000 0000 0000
0000 0000 0000 (bits 0...31. So, bit 0 == 1).
So, if in Little Endian mode, then in PowerPC terms the above "if" is testing
bit 0 of the flags field.
In which case, the compiler is generating assembly as: rlwinm  r0,r7,1,31,31

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

CODE::
MMU_FTR_TYPE_47x has 0x40
cur_cpu_spec->mmu_features -> 0x140040

static inline int mmu_has_feature(unsigned long feature) {
        return(cur_cpu_spec->mmu_features & feature); }

Assembly:
andis.  r10,r11,512

What the above assembly instruction does is basically this: r10 = r11 & (512 <<
16) = r11 & 0x02000000 (i.e. bit 6 is getting tested).
Now, where does 512 come from? Let's look at MMU_FTR_TYPE_47x:

MMU_FTR_TYPE_47x should ideally be seen by the compiler as 0000 0000 0000 0000
0000 0000 0100 0000 (bits 0...31. So, bit 25 == 1).
So, if in Little Endian mode, then in PowerPC terms the above "&" operation is
testing bit 25 of the cur_cpu_spec->mmu_features field.
In which case, the compiler should be generating assembly as: andi.  r10,r11,64

However, it appears the compiler sees MMU_FTR_TYPE_47x as 0000 0010 0000 0000
0000 0000 0000 0000 (bits 0...31. So, bit 6 == 1).
So, if in Little Endian mode, then in PowerPC terms the above "&" is testing
bit 6 of the cur_cpu_spec->mmu_features field.
In which case, the compiler is generating assembly as: andis.  r10,r11,512

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Therefore it appears that constants are being interrupted wrongly i.e as a
mirror image.

Few Observations:
1) After I compile a small piece of code and run " file <binary> " the output
is 

ELF 32-bit LSB executable, PowerPC, Versoin 1 (SYSV), dynamically linked (uses
shared libs), for GNU/Linux 2.6.39, not stripped

2) __LITTLE_ENDIAN is defined.

3) Though the above 2 are true the machine is still working in Big Endian.
confirmed by writing 1 into b and reading a[0]. which reads 0.
union endian{
      unsigned int b;
      unsigned char a[4] ;
}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]