This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/50705] Wrong assembly generated for bitwise AND for ppc 476
- From: "santoshkumar.a at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 19 Oct 2011 14:22:16 +0000
- Subject: [Bug target/50705] Wrong assembly generated for bitwise AND for ppc 476
- Auto-submitted: auto-generated
- References: <bug-50705-4@http.gcc.gnu.org/bugzilla/>
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] ;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++